ZQuest Classic Coverage Report


Directory: src/
File: src/zc/ffscript.cpp
Date: 2026-01-17 08:03:16
Exec Total Coverage
Lines: 6400 17183 37.2%
Functions: 440 663 66.4%
Branches: 3348 12718 26.3%

Line Branch Exec Source
1 #include <cstdint>
2 #include <deque>
3 #include <limits>
4 #include <memory>
5 #include <string>
6 #include <sstream>
7 #include <math.h>
8 #include <cstdio>
9 #include <algorithm>
10 #include <ranges>
11 //
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <fstream>
17 #include <fmt/format.h>
18 #include <fmt/ranges.h>
19 //
20
21 #include "base/check.h"
22 #include "base/expected.h"
23 #include "base/handles.h"
24 #include "base/general.h"
25 #include "base/mapscr.h"
26 #include "base/qrs.h"
27 #include "base/dmap.h"
28 #include "base/msgstr.h"
29 #include "base/packfile.h"
30 #include "base/misctypes.h"
31 #include "base/initdata.h"
32 #include "base/scc.h"
33 #include "base/version.h"
34 #include "new_subscr.h"
35 #include "zc/maps.h"
36 #include "zasm/serialize.h"
37 #include "zasm/table.h"
38 #include "zc/replay.h"
39 #include "zc/scripting/array_manager.h"
40 #include "zc/scripting/arrays.h"
41 #include "zc/scripting/common.h"
42 #include "zc/scripting/script_object.h"
43 #include "zc/scripting/sram.h"
44 #include "zc/scripting/string_utils.h"
45 #include "zc/scripting/types.h"
46 #include "zc/zasm_optimize.h"
47 #include "zc/zasm_utils.h"
48 #include "zc/zc_ffc.h"
49 #include "zc/zc_sys.h"
50 #include "zc/jit.h"
51 #include "zc/script_debug.h"
52 #include "base/zc_alleg.h"
53 #include "base/zc_math.h"
54 #include "base/zc_array.h"
55 #include "zc/ffscript.h"
56 #include "zc/render.h"
57 #include "zc/zc_subscr.h"
58 #include <time.h>
59 #include "zc/script_drawing.h"
60 #include "base/util.h"
61 #include "zc/ending.h"
62 #include "zc/combos.h"
63 #include "drawing.h"
64 #include "base/colors.h"
65 #include "pal.h"
66 #include "zinfo.h"
67 #include "subscr.h"
68 #include "zc_list_data.h"
69 #include "music_playback.h"
70 #include "iter.h"
71 #include <sstream>
72
73 #include "zc/zelda.h"
74 #include "particles.h"
75 #include "zc/hero.h"
76 #include "zc/guys.h"
77 #include "gamedata.h"
78 #include "zc/zc_init.h"
79 #include "base/zsys.h"
80 #include "base/misctypes.h"
81 #include "zc/title.h"
82 #include "zscriptversion.h"
83
84 #include "pal.h"
85 #include "base/zdefs.h"
86 #include "zc/rendertarget.h"
87
88 #include "hero_tiles.h"
89 #include "base/qst.h"
90
91 using namespace util;
92
93 using namespace util;
94 using std::ostringstream;
95
96 static ASM_DEFINE current_zasm_command;
97 static uint32_t current_zasm_register;
98 // If set, the next call to scripting_log_error_with_context will use this string in addition to whatever
99 // current_zasm_command and current_zasm_register refer to. Must unset after manually.
100 std::string current_zasm_extra_context;
101 // If set, the next call to scripting_log_error_with_context will use this string instead of whatever
102 // current_zasm_command and current_zasm_register refer to. Must unset after manually.
103 std::string current_zasm_context;
104
105 2175056 void scripting_log_error_with_context(std::string text)
106 {
107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2175056 times.
2175056 if (current_zasm_context.empty())
108 {
109 2175056 std::vector<const char*> context;
110
111
1/2
✓ Branch 0 taken 2175056 times.
✗ Branch 1 not taken.
2175056 const char* command_string = scripting_get_zasm_command_context_string(current_zasm_command);
112
2/2
✓ Branch 0 taken 387818 times.
✓ Branch 1 taken 1787238 times.
2175056 if (command_string)
113
1/2
✓ Branch 0 taken 387818 times.
✗ Branch 1 not taken.
387818 context.push_back(command_string);
114
115
1/2
✓ Branch 0 taken 2175056 times.
✗ Branch 1 not taken.
2175056 const char* register_string = scripting_get_zasm_register_context_string(current_zasm_register);
116
2/2
✓ Branch 0 taken 1005625 times.
✓ Branch 1 taken 1169431 times.
2175056 if (register_string)
117
1/2
✓ Branch 0 taken 1005625 times.
✗ Branch 1 not taken.
1005625 context.push_back(register_string);
118
119
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2175052 times.
2175056 if (!current_zasm_extra_context.empty())
120
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 context.push_back(current_zasm_extra_context.c_str());
121
122
2/2
✓ Branch 0 taken 1391030 times.
✓ Branch 1 taken 784026 times.
2175056 if (context.size())
123
3/6
✓ Branch 0 taken 1391030 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1391030 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1391030 times.
✗ Branch 5 not taken.
1391030 current_zasm_context = fmt::format("{}", fmt::join(context, ", "));
124 else
125 {
126
1/2
✓ Branch 0 taken 784026 times.
✗ Branch 1 not taken.
784026 Z_scripterrlog("%s\n", text.c_str());
127 784026 return;
128 }
129
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 784026 times.
✓ Branch 2 taken 1391030 times.
2175056 }
130
131 1391030 Z_scripterrlog("%s | %s\n", current_zasm_context.c_str(), text.c_str());
132 1391030 current_zasm_context = "";
133 1391030 current_zasm_extra_context = "";
134 2175056 }
135
136 // (type, index) => ScriptEngineData
137 430 std::map<std::pair<ScriptType, int>, ScriptEngineData> scriptEngineDatas;
138
139 extern byte use_dwm_flush;
140 uint8_t using_SRAM = 0;
141
142 int32_t hangcount = 0;
143 bool can_neg_array = true;
144
145 extern byte monochrome_console;
146
147 430 static std::map<script_id, ScriptDebugHandle> script_debug_handles;
148 ScriptDebugHandle* runtime_script_debug_handle;
149
150 430 CScriptDrawingCommands scriptdraws;
151 430 FFScript FFCore;
152
153 static UserDataContainer<script_array, 1000000> script_arrays = {script_object_type::array, "array"};
154 static UserDataContainer<user_paldata, MAX_USER_PALDATAS> user_paldatas = {script_object_type::paldata, "paldata"};
155 static UserDataContainer<user_rng, MAX_USER_RNGS> user_rngs = {script_object_type::rng, "rng"};
156 static UserDataContainer<user_stack, MAX_USER_STACKS> user_stacks = {script_object_type::stack, "stack"};
157 static UserDataContainer<user_bitmap, MAX_USER_BITMAPS> user_bitmaps = {script_object_type::bitmap, "bitmap"};
158
159 8102 script_array* create_script_array()
160 {
161 8102 return script_arrays.create();
162 }
163
164 404 void register_existing_script_array(script_array* array)
165 {
166 404 script_arrays.register_existing(array);
167 404 }
168
169 68 std::vector<script_array*> get_script_arrays()
170 {
171 68 std::vector<script_array*> result;
172
3/4
✓ Branch 0 taken 68 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 68 times.
✓ Branch 3 taken 558 times.
626 for (auto id : script_object_ids_by_type[script_arrays.type])
173 {
174
2/4
✓ Branch 0 taken 558 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 558 times.
✗ Branch 3 not taken.
558 result.push_back(&script_arrays[id]);
175 }
176 68 return result;
177
1/2
✓ Branch 0 taken 68 times.
✗ Branch 1 not taken.
68 }
178
179 14686 script_array* find_or_create_internal_script_array(script_array::internal_array_id internal_id)
180 {
181
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14686 times.
14686 if (!zasm_array_supports(internal_id.zasm_var))
182 {
183 scripting_log_error_with_context("Invalid internal array id: {}", internal_id.zasm_var);
184 return nullptr;
185 }
186
187
2/2
✓ Branch 0 taken 575532 times.
✓ Branch 1 taken 254 times.
575786 for (auto id : script_object_ids_by_type[script_arrays.type])
188 {
189 575532 auto object = static_cast<script_array*>(get_script_object_checked(id));
190 DCHECK(object);
191
5/6
✓ Branch 0 taken 575532 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 134883 times.
✓ Branch 3 taken 440649 times.
✓ Branch 4 taken 120451 times.
✓ Branch 5 taken 14432 times.
575532 if (!object->internal_expired && object->internal_id.has_value() && object->internal_id.value() == internal_id)
192 14432 return object;
193 }
194
195 254 auto array = script_arrays.create();
196
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 254 times.
254 if (array)
197 {
198 254 array->arr.setValid(true);
199 254 array->internal_id = internal_id;
200 // Retain a reference until the underlying engine object is destroyed.
201 254 script_object_ref_inc(array->id);
202 254 }
203 254 return array;
204 14686 }
205
206 2535645 static void expire_internal_script_arrays(ScriptType scriptType, int ref)
207 {
208
2/2
✓ Branch 0 taken 1357217 times.
✓ Branch 1 taken 1178428 times.
2535645 if (!ZScriptVersion::gc_arrays())
209 1357217 return;
210
211 // Expire internal arrays referring to this script object.
212 1178428 std::vector<uint32_t> retained_ids;
213
6/10
✓ Branch 0 taken 1178428 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1178428 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1178428 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 20414708 times.
✓ Branch 7 taken 1178428 times.
✓ Branch 8 taken 20414708 times.
✗ Branch 9 not taken.
21593136 for (auto& script_object : script_objects | std::views::values)
214 {
215
2/2
✓ Branch 0 taken 8808778 times.
✓ Branch 1 taken 11605930 times.
20414708 if (script_object->type != script_object_type::array)
216 8808778 continue;
217
218 11605930 auto array = static_cast<script_array*>(script_object.get());
219
3/4
✓ Branch 0 taken 2602 times.
✓ Branch 1 taken 11603328 times.
✓ Branch 2 taken 2602 times.
✗ Branch 3 not taken.
11605930 if (!array->internal_id.has_value() || array->internal_expired)
220 11603328 continue;
221
222
3/4
✓ Branch 0 taken 2602 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 240 times.
✓ Branch 3 taken 2362 times.
2602 if (array->internal_id->matches(scriptType, ref))
223 {
224
1/2
✓ Branch 0 taken 240 times.
✗ Branch 1 not taken.
240 retained_ids.push_back(array->id);
225
1/2
✓ Branch 0 taken 240 times.
✗ Branch 1 not taken.
240 array->get_retained_ids(retained_ids);
226 240 array->internal_expired = true;
227 240 }
228 }
229
230
2/2
✓ Branch 0 taken 263 times.
✓ Branch 1 taken 1178428 times.
1178691 for (auto id : retained_ids)
231
1/2
✓ Branch 0 taken 263 times.
✗ Branch 1 not taken.
263 script_object_ref_dec(id);
232 2535645 }
233
234 37536 static void expire_internal_script_arrays(ScriptType scriptType)
235 {
236
2/2
✓ Branch 0 taken 18404 times.
✓ Branch 1 taken 19132 times.
37536 if (!ZScriptVersion::gc_arrays())
237 18404 return;
238
239 // Expire internal arrays referring to this script object.
240 19132 std::vector<uint32_t> retained_ids;
241
6/10
✓ Branch 0 taken 19132 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19132 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 19132 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 109151 times.
✓ Branch 7 taken 19132 times.
✓ Branch 8 taken 109151 times.
✗ Branch 9 not taken.
128283 for (auto& script_object : script_objects | std::views::values)
242 {
243
2/2
✓ Branch 0 taken 10213 times.
✓ Branch 1 taken 98938 times.
109151 if (script_object->type != script_object_type::array)
244 10213 continue;
245
246 98938 auto array = static_cast<script_array*>(script_object.get());
247
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 98938 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
98938 if (!array->internal_id.has_value() || array->internal_expired)
248 98938 continue;
249
250 if (array->internal_id->matches(scriptType))
251 {
252 retained_ids.push_back(array->id);
253 array->get_retained_ids(retained_ids);
254 array->internal_expired = true;
255 }
256 }
257
258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19132 times.
19132 for (auto id : retained_ids)
259 script_object_ref_dec(id);
260 37536 }
261
262 153274086 script_array* checkArray(uint32_t id, bool skipError)
263 {
264 153274086 return script_arrays.check(id, skipError);
265 }
266
267 16869421 void script_bitmaps::update()
268 {
269 16869421 auto ids = script_object_ids_by_type[user_bitmaps.type];
270
2/2
✓ Branch 0 taken 41321692 times.
✓ Branch 1 taken 16869421 times.
58191113 for (auto id : ids)
271 {
272
1/2
✓ Branch 0 taken 41321692 times.
✗ Branch 1 not taken.
41321692 auto& bitmap = user_bitmaps[id];
273
3/4
✓ Branch 0 taken 41321692 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1509228 times.
✓ Branch 3 taken 39812464 times.
41321692 if (bitmap.is_freeing())
274 {
275
1/2
✓ Branch 0 taken 1509228 times.
✗ Branch 1 not taken.
1509228 bitmap.mark_can_del();
276
1/2
✓ Branch 0 taken 1509228 times.
✗ Branch 1 not taken.
1509228 delete_script_object(id);
277 1509228 }
278 }
279 16869421 }
280
281 380411 user_bitmap& script_bitmaps::get(int32_t id)
282 {
283
3/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 380403 times.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
380411 static user_bitmap fake;
284
285 380411 current_zasm_context = "script drawing";
286
1/2
✓ Branch 0 taken 380411 times.
✗ Branch 1 not taken.
380411 if (auto bitmap = user_bitmaps.check(id))
287 {
288 380411 current_zasm_context = "";
289 380411 return *bitmap;
290 }
291
292 return fake;
293 380411 }
294
295 script_bitmaps scb;
296 430 user_rng nulrng;
297 430 zc_randgen script_rnggens[MAX_USER_RNGS];
298
299 FONT *get_zc_font(int index);
300
301 int32_t combopos_modified = -1;
302 static std::vector<word> combo_id_cache;
303
304 int32_t CScriptDrawingCommands::GetCount()
305 {
306 al_trace("current number of draws is: %d\n", count);
307 return count;
308 }
309
310 // Decodes a `mapdataref` (reference number) for a temporary screen.
311 //
312 // A mapdataref can refer to:
313 //
314 // - the canonical mapscr data, loaded via `Game->LoadMapData(int map, int screen)`
315 // - a temporary mapscr, loaded via `Game->LoadTempScreen(int layer, int? screen)`
316 // - a temporary mapscr, loaded via `Game->LoadScrollingScreen(int layer, int? screen)`
317 //
318 // The canonical maprefs are >=0, and temporary ones are all negative.
319 //
320 // If temporary, and loaded without specifiying a screen index, we allow combo array variables (like
321 // `ComboX[pos]`) to address any rpos in the region. Otherwise, only positions in the exact screen
322 // referenced by `mapdataref` can be used (0-175). See ResolveMapdataPos.
323 132609693 mapdata decode_mapdata_ref(int ref)
324 {
325
2/2
✓ Branch 0 taken 37064919 times.
✓ Branch 1 taken 95544774 times.
132609693 if (ref >= 0)
326 {
327
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37064919 times.
37064919 if (ref >= TheMaps.size())
328 return mapdata{};
329
330 37064919 int screen = ref % MAPSCRS;
331 37064919 mapscr* scr = &TheMaps[ref];
332 37064919 return mapdata{mapdata_type::CanonicalScreen, scr, scr, screen, 0};
333 }
334
335 // Negative values are for temporary screens.
336
337 95544774 ref = -(ref + 1);
338 95544774 bool is_scrolling = ref & 1;
339 95544774 bool is_region = ref & 2;
340 95544774 int screen = (ref & 0x0000FF00) >> 8;
341 95544774 int layer = (ref & 0x00FF0000) >> 16;
342
343
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 95544774 times.
95544774 if (is_region)
344 {
345
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 95544774 times.
95544774 if (is_scrolling)
346 screen = scrolling_region.origin_screen;
347 else
348 95544774 screen = cur_screen;
349 95544774 }
350
351 95544774 mapscr* base_scr = nullptr;
352 95544774 mapscr* scr = nullptr;
353
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 95544774 times.
95544774 if (is_scrolling)
354 {
355 int index = screen * 7 + layer;
356 if (index >= 0 && index < FFCore.ScrollingScreensAll.size())
357 {
358 base_scr = FFCore.ScrollingScreensAll[screen * 7];
359 scr = FFCore.ScrollingScreensAll[index];
360 }
361 }
362 else
363 {
364
3/6
✓ Branch 0 taken 95544774 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 95544774 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 95544774 times.
95544774 if (layer >= 0 && layer <= 6 && is_in_current_region(screen))
365 {
366 95544774 base_scr = get_scr_layer(screen, 0);
367 95544774 scr = get_scr_layer(screen, layer);
368 95544774 }
369 }
370
371
1/2
✓ Branch 0 taken 95544774 times.
✗ Branch 1 not taken.
95544774 if (!scr)
372 return mapdata{};
373
374 95544774 auto type = mapdata_type::None;
375
2/4
✓ Branch 0 taken 95544774 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 95544774 times.
✗ Branch 3 not taken.
95544774 if (is_region && is_scrolling)
376 type = mapdata_type::TemporaryScrollingRegion;
377
2/4
✓ Branch 0 taken 95544774 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 95544774 times.
95544774 else if (is_region && !is_scrolling)
378 95544774 type = mapdata_type::TemporaryCurrentRegion;
379 else if (!is_region && is_scrolling)
380 type = mapdata_type::TemporaryScrollingScreen;
381 else if (!is_region && !is_scrolling)
382 type = mapdata_type::TemporaryCurrentScreen;
383
384 95544774 return mapdata{type, base_scr, scr, screen, layer};
385 132609693 }
386
387 3767772 static int create_mapdata_temp_ref(mapdata_type type, int screen, int layer)
388 {
389
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3767772 times.
3767772 bool is_scrolling = type == mapdata_type::TemporaryScrollingScreen || type == mapdata_type::TemporaryScrollingRegion;
390
2/2
✓ Branch 0 taken 182518 times.
✓ Branch 1 taken 3585254 times.
3767772 bool is_region = type == mapdata_type::TemporaryScrollingRegion || type == mapdata_type::TemporaryCurrentRegion;
391
392 3767772 int ref = 0;
393 3767772 ref |= is_scrolling ? 1 : 0;
394 3767772 ref |= is_region ? 2 : 0;
395
1/2
✓ Branch 0 taken 3767772 times.
✗ Branch 1 not taken.
3767772 if (!is_region)
396 ref |= ((screen & 0xFF) << 8);
397 3767772 ref |= ((layer & 0xFF) << 16);
398 3767772 return -ref-1;
399 }
400
401 mapscr* GetScrollingMapscr(int layer, int x, int y)
402 {
403 if (!screenscrolling)
404 return nullptr;
405
406 int screen = scrolling_region.origin_screen + map_scr_xy_to_index(x / 256, y / 176);
407 mapscr* m = FFCore.ScrollingScreensAll[screen * 7 + layer];
408 if (!m || !m->is_valid())
409 return nullptr;
410
411 return m;
412 }
413
414 151527 int32_t getMap(int32_t ref)
415 {
416
1/15
✗ Branch 0 not taken.
✓ Branch 1 taken 151527 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
151527 switch(ref)
417 {
418 case MAPSCR_TEMP0:
419 return cur_map+1;
420 case MAPSCR_TEMP1:
421 return origin_scr->layermap[0];
422 case MAPSCR_TEMP2:
423 return origin_scr->layermap[1];
424 case MAPSCR_TEMP3:
425 return origin_scr->layermap[2];
426 case MAPSCR_TEMP4:
427 return origin_scr->layermap[3];
428 case MAPSCR_TEMP5:
429 return origin_scr->layermap[4];
430 case MAPSCR_TEMP6:
431 return origin_scr->layermap[5];
432 case MAPSCR_SCROLL0:
433 return scrolling_map+1;
434 case MAPSCR_SCROLL1:
435 return special_warp_return_scr->layermap[0];
436 case MAPSCR_SCROLL2:
437 return special_warp_return_scr->layermap[1];
438 case MAPSCR_SCROLL3:
439 return special_warp_return_scr->layermap[2];
440 case MAPSCR_SCROLL4:
441 return special_warp_return_scr->layermap[3];
442 case MAPSCR_SCROLL5:
443 return special_warp_return_scr->layermap[4];
444 case MAPSCR_SCROLL6:
445 return special_warp_return_scr->layermap[5];
446 default:
447 151527 return (ref / MAPSCRS + 1);
448 }
449 151527 }
450 314379 int32_t getScreen(int32_t ref)
451 {
452
1/15
✗ Branch 0 not taken.
✓ Branch 1 taken 314379 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
314379 switch(ref)
453 {
454 case MAPSCR_TEMP0:
455 return cur_screen;
456 case MAPSCR_TEMP1:
457 return origin_scr->layerscreen[0];
458 case MAPSCR_TEMP2:
459 return origin_scr->layerscreen[1];
460 case MAPSCR_TEMP3:
461 return origin_scr->layerscreen[2];
462 case MAPSCR_TEMP4:
463 return origin_scr->layerscreen[3];
464 case MAPSCR_TEMP5:
465 return origin_scr->layerscreen[4];
466 case MAPSCR_TEMP6:
467 return origin_scr->layerscreen[5];
468 case MAPSCR_SCROLL0:
469 return scrolling_hero_screen;
470 case MAPSCR_SCROLL1:
471 return special_warp_return_scr->layerscreen[0];
472 case MAPSCR_SCROLL2:
473 return special_warp_return_scr->layerscreen[1];
474 case MAPSCR_SCROLL3:
475 return special_warp_return_scr->layerscreen[2];
476 case MAPSCR_SCROLL4:
477 return special_warp_return_scr->layerscreen[3];
478 case MAPSCR_SCROLL5:
479 return special_warp_return_scr->layerscreen[4];
480 case MAPSCR_SCROLL6:
481 return special_warp_return_scr->layerscreen[5];
482 default:
483 314379 return (ref % MAPSCRS);
484 }
485 314379 }
486
487 655056392 static ffcdata* get_ffc(ffc_id_t ffc_id)
488 {
489 655056392 return &get_scr_for_region_index_offset(ffc_id / MAXFFCS)->getFFC(ffc_id % MAXFFCS);
490 }
491
492 105844 dword get_subref(int sub, byte ty, byte pg, word ind)
493 {
494 byte s;
495
2/2
✓ Branch 0 taken 79480 times.
✓ Branch 1 taken 26364 times.
105844 if(sub == -1) //special; load current
496 {
497
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26364 times.
26364 if (new_sub_indexes[ty] < 0) return 0;
498 26364 s = new_sub_indexes[ty];
499 26364 }
500
1/2
✓ Branch 0 taken 79480 times.
✗ Branch 1 not taken.
79480 else if(unsigned(sub) < 256)
501 79480 s = sub;
502 else return 0;
503 105844 ++ty; //type is offset by 1
504 105844 return (s<<24)|(pg<<16)|((ty&0x7)<<13)|(ind&0x1FFF);
505 105844 }
506 425312 std::tuple<byte,int8_t,byte,word> from_subref(dword ref)
507 {
508 425312 byte type = (ref>>13)&0x07;
509
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 425312 times.
425312 if(!type)
510 return { 0, -1, 0, 0 };
511
512 425312 byte sub = (ref>>24)&0xFF;
513 425312 byte pg = (ref>>16)&0xFF;
514 425312 word ind = (ref)&0x1FFF;
515 425312 return { sub, type-1, pg, ind };
516 425312 }
517
518 345835 std::tuple<ZCSubscreen*,SubscrPage*,SubscrWidget*,byte> load_subscreen_ref(dword ref)
519 {
520 1729175 auto [sub,ty,pg,ind] = from_subref(ref);
521 345835 ZCSubscreen* sbscr = nullptr;
522 345835 SubscrPage* sbpg = nullptr;
523 345835 SubscrWidget* sbwidg = nullptr;
524
1/5
✗ Branch 0 not taken.
✓ Branch 1 taken 345835 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
345835 switch(ty)
525 {
526 case sstACTIVE:
527
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 345835 times.
345835 if(sub < subscreens_active.size())
528 345835 sbscr = &subscreens_active[sub];
529 345835 break;
530 case sstPASSIVE:
531 if(sub < subscreens_passive.size())
532 sbscr = &subscreens_passive[sub];
533 break;
534 case sstOVERLAY:
535 if(sub < subscreens_overlay.size())
536 sbscr = &subscreens_overlay[sub];
537 break;
538 case sstMAP:
539 if(sub < subscreens_map.size())
540 sbscr = &subscreens_map[sub];
541 break;
542 }
543
1/2
✓ Branch 0 taken 345835 times.
✗ Branch 1 not taken.
345835 if(sbscr)
544 {
545
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 345835 times.
345835 if(pg < sbscr->pages.size())
546 691670 sbpg = &sbscr->pages[pg];
547 345835 }
548 else return { nullptr, nullptr, nullptr, -1 }; //no subscreen
549
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 345835 times.
345835 if(sbpg)
550 {
551
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 345835 times.
345835 if(ind < sbpg->size())
552 691670 sbwidg = sbpg->at(ind);
553 345835 }
554 345835 return { sbscr, sbpg, sbwidg, ty };
555 345835 }
556 186065 std::pair<ZCSubscreen*,byte> load_subdata(dword ref)
557 {
558 186065 auto [sub,_pg,_widg,ty] = load_subscreen_ref(ref);
559 186065 return { sub, ty };
560 }
561 56028 std::pair<SubscrPage*,byte> load_subpage(dword ref)
562 {
563 56028 auto [_sub,pg,_widg,ty] = load_subscreen_ref(ref);
564 56028 return { pg, ty };
565 }
566 103742 std::pair<SubscrWidget*,byte> load_subwidg(dword ref)
567 {
568 103742 auto [_sub,_pg,widg,ty] = load_subscreen_ref(ref);
569 103742 return { widg, ty };
570 }
571
572 #include "zconsole/ConsoleLogger.h"
573
574 //no ifdef here
575 extern CConsoleLoggerEx zscript_coloured_console;
576
577 bool FFScript::isNumber(char chr)
578 {
579 if ( chr >= '0' )
580 {
581 if ( chr <= '9' ) return true;
582 }
583 return false;
584 }
585
586 int32_t FFScript::ilen(char *p)
587 {
588 int32_t ret = 0; int32_t pos = 0;
589 if(p[pos] == '-')
590 ret++;
591 for(; FFCore.isNumber(p[pos + ret]); ++ret);
592 return ret;
593 }
594
595 int32_t FFScript::atox(char *ip_str)
596 {
597 char tmp[2]={'2','\0'};
598 int32_t op_val=0, i=0, ip_len = strlen(ip_str);
599
600 if(strncmp(ip_str, "0x", 2) == 0)
601 {
602 ip_str +=2;
603 ip_len -=2;
604 }
605
606 for(i=0;i<ip_len;i++)
607 {
608 op_val *= 0x10;
609 switch(ip_str[i])
610 {
611 case 'a':
612 op_val += 0xa;
613 break;
614 case 'b':
615 op_val += 0xb;
616 break;
617 case 'c':
618 op_val += 0xc;
619 break;
620 case 'd':
621 op_val += 0xd;
622 break;
623 case 'e':
624 op_val += 0xe;
625 break;
626 case 'f':
627 op_val += 0xf;
628 break;
629 case '0':
630 case '1':
631 case '2':
632 case '3':
633 case '4':
634 case '5':
635 case '6':
636 case '7':
637 case '8':
638 case '9':
639 tmp[0] = ip_str[i];
640 op_val += atoi(tmp);
641 break;
642 default :
643 op_val += 0x0;
644 break;
645 }
646 }
647 return op_val;
648 }
649
650 char runningItemScripts[256] = {0};
651
652 extern int32_t directItemA;
653 extern int32_t directItemB;
654 extern int32_t directItemX;
655 extern int32_t directItemY;
656
657
658 #ifdef _MSC_VER
659 #pragma warning ( disable : 4800 ) //int32_t to bool town. population: lots.
660 #endif
661
662 //! New datatype vars for 2.54:
663
664 //spritedata sp->member
665
666
667 using std::string;
668
669 extern char *guy_string[];
670 extern int32_t skipcont;
671
672 PALETTE tempgreypal; //Palettes go here. This is used for Greyscale() / Monochrome()
673 PALETTE userPALETTE[256]; //Palettes go here. This is used for Greyscale() / Monochrome()
674 PALETTE tempblackpal; //Used for storing the palette while fading to black
675
676 byte FF_hero_action; //This way, we can make safe replicas of internal Hero actions to be set by script.
677
678 int32_t FF_screenbounds[4]; //edges of the screen, left, right, top, bottom used for where to scroll.
679 int32_t FF_screen_dimensions[4]; //height, width, displaywidth, displayheight
680 int32_t FF_subscreen_dimensions[4];
681 int32_t FF_eweapon_removal_bounds[4]; //left, right, top, bottom coordinates for automatic eweapon removal.
682 int32_t FF_lweapon_removal_bounds[4]; //left, right, top, bottom coordinates for automatic lweapon removal.
683 int32_t FF_clocks[FFSCRIPTCLASS_CLOCKS]; //Will be used for Heroaction, anims, and so forth
684 byte ScriptDrawingRules[SCRIPT_DRAWING_RULES];
685 int32_t FF_UserMidis[NUM_USER_MIDI_OVERRIDES]; //MIDIs to use for Game Over, and similar to override system defaults.
686
687 //We gain some speed by not passing as arguments
688 int32_t sarg1;
689 int32_t sarg2;
690 int32_t sarg3;
691 vector<int32_t> *sargvec;
692 string *sargstr;
693 refInfo *ri;
694 script_data *curscript;
695 int32_t(*stack)[MAX_STACK_SIZE];
696 int32_t(*ret_stack)[MAX_CALL_FRAMES];
697 vector<int32_t> zs_vargs;
698 ScriptType curScriptType;
699 word curScriptNum;
700 int32_t curScriptIndex;
701 bool script_funcrun;
702 string* destructstr;
703 size_t gen_frozen_index;
704
705 static vector<ScriptType> curScriptType_cache;
706 static vector<int32_t> curScriptNum_cache;
707 static vector<int32_t> curScriptIndex_cache;
708 static vector<int32_t> sarg1cache;
709 static vector<int32_t> sarg2cache;
710 static vector<int32_t> sarg3cache;
711 static vector<vector<int32_t>*> sargvec_cache;
712 static vector<string*> sargstr_cache;
713 static vector<refInfo*> ricache;
714 static vector<script_data*> sdcache;
715 static vector<int32_t(*)[MAX_STACK_SIZE]> stackcache;
716 static vector<int32_t(*)[MAX_CALL_FRAMES]> ret_stack_cache;
717 231219 void push_ri()
718 {
719 231219 sarg1cache.push_back(sarg1);
720 231219 sarg2cache.push_back(sarg2);
721 231219 sarg3cache.push_back(sarg3);
722 231219 curScriptType_cache.push_back(curScriptType);
723 231219 curScriptNum_cache.push_back(curScriptNum);
724 231219 curScriptIndex_cache.push_back(curScriptIndex);
725 231219 sargvec_cache.push_back(sargvec);
726 231219 sargstr_cache.push_back(sargstr);
727 231219 ricache.push_back(ri);
728 231219 sdcache.push_back(curscript);
729 231219 stackcache.push_back(stack);
730 231219 ret_stack_cache.push_back(ret_stack);
731 231219 }
732 231219 void pop_ri()
733 {
734 231219 sarg1 = sarg1cache.back(); sarg1cache.pop_back();
735 231219 sarg2 = sarg2cache.back(); sarg2cache.pop_back();
736 231219 sarg3 = sarg3cache.back(); sarg3cache.pop_back();
737 231219 curScriptType = curScriptType_cache.back(); curScriptType_cache.pop_back();
738 231219 curScriptNum = curScriptNum_cache.back(); curScriptNum_cache.pop_back();
739 231219 curScriptIndex = curScriptIndex_cache.back(); curScriptIndex_cache.pop_back();
740 231219 sargvec = sargvec_cache.back(); sargvec_cache.pop_back();
741 231219 sargstr = sargstr_cache.back(); sargstr_cache.pop_back();
742 231219 ri = ricache.back(); ricache.pop_back();
743 231219 curscript = sdcache.back(); sdcache.pop_back();
744 231219 stack = stackcache.back(); stackcache.pop_back();
745 231219 ret_stack = ret_stack_cache.back(); ret_stack_cache.pop_back();
746 231219 }
747
748 //START HELPER FUNCTIONS
749 ///-------------------------------------//
750 // Helper Functions //
751 ///-------------------------------------//
752
753 2 static void log_stack_overflow_error()
754 {
755
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 scripting_log_error_with_context("Stack overflow!");
756 2 }
757
758 2 static void log_call_limit_error()
759 {
760 2 scripting_log_error_with_context("Function call limit reached! Too much recursion. Max nested function calls is {}", MAX_CALL_FRAMES);
761 2 }
762
763 41152647 void SH::write_stack(const uint32_t sp, const int32_t value)
764 {
765
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41152647 times.
41152647 if (sp >= MAX_STACK_SIZE)
766 {
767 log_stack_overflow_error();
768 ri->overflow = true;
769 return;
770 }
771
772 41152647 (*stack)[sp] = value;
773 41152647 }
774
775 983897606 int32_t SH::read_stack(const uint32_t sp)
776 {
777
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 983897606 times.
983897606 if (sp >= MAX_STACK_SIZE)
778 {
779 log_stack_overflow_error();
780 ri->overflow = true;
781 return -10000;
782 }
783
784 983897606 return (*stack)[sp];
785 983897606 }
786
787 ///----------------------------//
788 // Misc. //
789 ///----------------------------//
790
791 byte flagpos;
792 int32_t flagval;
793 21612004 void clear_ornextflag()
794 {
795 21612004 flagpos = 0;
796 21612004 flagval = 0;
797 21612004 }
798 147024201 void ornextflag(bool flag)
799 {
800
2/2
✓ Branch 0 taken 144842444 times.
✓ Branch 1 taken 2181757 times.
147024201 if(flag) flagval |= 1<<flagpos;
801 147024201 ++flagpos;
802 147024201 }
803
804 11180909 int32_t get_screenflags(mapscr *m, int32_t flagset)
805 {
806 11180909 clear_ornextflag();
807
808
5/11
✓ Branch 0 taken 4822494 times.
✓ Branch 1 taken 6266256 times.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 52 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 92096 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
11180909 switch(flagset)
809 {
810 case 0: // Room Type
811 4822494 ornextflag(m->flags6&1);
812 4822494 ornextflag(m->flags6&2);
813 4822494 ornextflag(m->flags7&8);
814 4822494 break;
815
816 case 1: // View
817 6266256 ornextflag(m->flags3&8);
818 6266256 ornextflag(m->flags7&16);
819 6266256 ornextflag(m->flags3&16);
820 6266256 ornextflag(m->flags3&64);
821 6266256 ornextflag(m->flags7&2);
822 6266256 ornextflag(m->flags7&1);
823 6266256 ornextflag(m->flags&fDARK);
824 6266256 ornextflag(m->flags9&fDARK_DITHER);
825 6266256 ornextflag(m->flags9&fDARK_TRANS);
826 6266256 break;
827
828 case 2: // Secrets
829 11 ornextflag(m->flags&1);
830 11 ornextflag(m->flags5&16);
831 11 ornextflag(m->flags6&4);
832 11 ornextflag(m->flags6&32);
833 11 break;
834
835 case 3: // Warp
836 ornextflag(m->flags5&4);
837 ornextflag(m->flags5&8);
838 ornextflag(m->flags&64);
839 ornextflag(m->flags8&64);
840 ornextflag(m->flags3&32);
841 ornextflag(m->flags9&fDISABLE_MIRROR);
842 ornextflag(m->flags10&fMAZE_CAN_GET_LOST);
843 ornextflag(m->flags10&fMAZE_LOOPY);
844 break;
845
846 case 4: // Item
847 52 ornextflag(m->flags3&1);
848 52 ornextflag(m->flags7&4);
849 52 ornextflag(m->flags8&0x40);
850 52 ornextflag(m->flags8&0x80);
851 52 ornextflag(m->flags9&0x01);
852 52 ornextflag(m->flags9&0x02);
853 52 ornextflag(m->flags9&fBELOWRETURN);
854 52 break;
855
856 case 5: // Combo
857 ornextflag((m->flags2>>4)&2);
858 ornextflag(m->flags3&2);
859 ornextflag(m->flags5&2);
860 ornextflag(m->flags6&64);
861 break;
862
863 case 6: // Save
864 ornextflag(m->flags4&64);
865 ornextflag(m->flags4&128);
866 ornextflag(m->flags6&8);
867 ornextflag(m->flags6&16);
868 break;
869
870 case 7: // FFC
871 ornextflag(m->flags6&128);
872 ornextflag(m->flags5&128);
873 break;
874
875 case 8: // Whistle
876 ornextflag(m->flags&16);
877 ornextflag(m->flags7&64);
878 ornextflag(m->flags7&128);
879 break;
880
881 case 9: // Misc
882 92096 ornextflag(m->flags&32);
883 92096 ornextflag(m->flags5&64);
884 92096 flagval |= m->flags8<<2;
885 92096 break;
886 }
887
888 11180909 return flagval;
889 }
890
891 4476010 int32_t get_screeneflags(mapscr *m, int32_t flagset)
892 {
893 4476010 clear_ornextflag();
894
895
2/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 4475708 times.
✓ Branch 3 taken 302 times.
4476010 switch(flagset)
896 {
897 case 0:
898 flagval |= m->flags11&0x1F;
899 break;
900
901 case 1:
902 4475708 ornextflag(m->flags11&32);
903 4475708 ornextflag(m->flags11&64);
904 4475708 ornextflag(m->flags3&4);
905 4475708 ornextflag(m->flags11&128);
906 4475708 ornextflag((m->flags2>>4)&4);
907 4475708 break;
908
909 case 2:
910 302 ornextflag(m->flags3&128);
911 302 ornextflag(m->flags&2);
912 302 ornextflag((m->flags2>>4)&8);
913 302 ornextflag(m->flags4&16);
914 302 ornextflag(m->flags9&fENEMY_WAVES);
915 302 break;
916 }
917
918 4476010 return flagval;
919 }
920
921 551246 int32_t get_mi(mapdata const& ref)
922 {
923
1/2
✓ Branch 0 taken 551246 times.
✗ Branch 1 not taken.
551246 if (ref.canonical())
924 {
925
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 551246 times.
551246 if (ref.screen >= MAPSCRSNORMAL) return -1;
926 551246 return mapind(ref.scr->map, ref.screen);
927 }
928 else if (ref.current())
929 {
930 if (ref.screen >= MAPSCRSNORMAL) return -1;
931 return mapind(cur_map, ref.screen);
932 }
933 else if (ref.scrolling())
934 {
935 if (ref.screen >= MAPSCRSNORMAL) return -1;
936 return mapind(scrolling_map, ref.screen);
937 }
938
939 return -1;
940 551246 }
941 int32_t get_mi(int32_t ref)
942 {
943 return get_mi(decode_mapdata_ref(ref));
944 }
945
946 int32_t get_ref_map_index(int32_t ref)
947 {
948 if (ref >= 0)
949 return ref;
950
951 auto result = decode_mapdata_ref(ref);
952 if (result.current())
953 {
954 return map_screen_index(cur_map, result.screen);
955 }
956 else if (result.scrolling())
957 {
958 return map_screen_index(scrolling_map, result.screen);
959 }
960
961 return -1;
962 }
963
964 template <typename T>
965 348982651 static T* ResolveSprite(int32_t uid, const char* name)
966 {
967
8/10
✓ Branch 0 taken 109888484 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1642483 times.
✓ Branch 3 taken 597888 times.
✓ Branch 4 taken 169197407 times.
✓ Branch 5 taken 2612 times.
✓ Branch 6 taken 61041698 times.
✓ Branch 7 taken 183114 times.
✓ Branch 8 taken 6428965 times.
✗ Branch 9 not taken.
348982651 if (!uid)
968 {
969
6/20
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 597888 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 597888 times.
✓ Branch 8 taken 2612 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2612 times.
✓ Branch 12 taken 183114 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 183114 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
783614 scripting_log_error_with_context("Invalid sprite: null pointer");
970 783614 return nullptr;
971 }
972
973
8/10
✗ Branch 0 not taken.
✓ Branch 1 taken 109888484 times.
✓ Branch 2 taken 180 times.
✓ Branch 3 taken 1642303 times.
✓ Branch 4 taken 7108 times.
✓ Branch 5 taken 169190299 times.
✓ Branch 6 taken 20166 times.
✓ Branch 7 taken 61021532 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 6428965 times.
348199037 if (auto s = sprite::getByUID(uid))
974 {
975
9/18
✗ Branch 0 not taken.
✓ Branch 1 taken 109888484 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1642303 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1642303 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 169190299 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 169190299 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 61021532 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 61021532 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 6428965 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 6428965 times.
348171583 if (auto s2 = dynamic_cast<T*>(s))
976 348171583 return s2;
977
978 scripting_log_error_with_context("Invalid sprite using UID = {} - but that sprite is not a {}", uid, name);
979 return nullptr;
980 }
981
982 27454 scripting_log_error_with_context("Invalid sprite using UID = {} - but that sprite does not exist", uid);
983 27454 return nullptr;
984 348982651 }
985
986 109888484 sprite* ResolveBaseSprite(int32_t uid)
987 {
988 109888484 return ResolveSprite<sprite>(uid, "sprite");
989 }
990
991 2240371 item* ResolveItemSprite(int32_t uid)
992 {
993 2240371 return ResolveSprite<item>(uid, "item");
994 }
995
996 169200007 enemy* ResolveNpc(int32_t uid)
997 {
998 169200007 return ResolveSprite<enemy>(uid, "npc");
999 }
1000
1001 static weapon* ResolveEWeapon_checkSpriteList(int32_t uid)
1002 {
1003 // Check here first (for the error logging.)
1004 const char* name = "eweapon";
1005 auto spr = ResolveSprite<weapon>(uid, name);
1006
1007 // Double check this is from the right sprite list.
1008 if (spr && !Ewpns.getByUID(uid))
1009 {
1010 scripting_log_error_with_context("Invalid sprite using UID = {} - but that sprite is not a {}", uid, name);
1011 return nullptr;
1012 }
1013
1014 return spr;
1015 }
1016
1017 598 static weapon* ResolveLWeapon_checkSpriteList(int32_t uid)
1018 {
1019 // Check here first (for the error logging.)
1020 598 const char* name = "lweapon";
1021 598 auto spr = ResolveSprite<weapon>(uid, name);
1022
1023 // Double check this is from the right sprite list.
1024
2/4
✓ Branch 0 taken 598 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 598 times.
598 if (spr && !Lwpns.getByUID(uid))
1025 {
1026 scripting_log_error_with_context("Invalid sprite using UID = {} - but that sprite is not a {}", uid, name);
1027 return nullptr;
1028 }
1029
1030 598 return spr;
1031 598 }
1032
1033 // For compat, get the first `combo_trigger` of the current `ri->combodataref`
1034 3224 combo_trigger* get_first_combo_trigger()
1035 {
1036 3224 int ref = GET_REF(combodataref);
1037
2/4
✓ Branch 0 taken 3224 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3224 times.
3224 if(ref < 0 || ref > (MAXCOMBOS-1) )
1038 return nullptr;
1039
2/2
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 3085 times.
3224 if(combobuf[ref].triggers.empty())
1040 139 return &(combobuf[ref].triggers.emplace_back());
1041 3085 return &(combobuf[ref].triggers[0]);
1042 3224 }
1043 // Get the combo trigger pointed to by `ref` (usually ri->combotriggerref)
1044 combo_trigger* get_combo_trigger(dword ref)
1045 {
1046 byte idx = (ref >> 24) & 0xFF;
1047 dword cid = ref & 0x00FFFFFF;
1048 if(cid >= MAXCOMBOS)
1049 {
1050 scripting_log_error_with_context("Invalid combotrigger ID: {}-{}", idx, cid);
1051 return nullptr;
1052 }
1053 newcombo& cmb = combobuf[cid];
1054 if(idx >= cmb.triggers.size())
1055 {
1056 scripting_log_error_with_context("Invalid combotrigger ID: {}-{}", idx, cid);
1057 return nullptr;
1058 }
1059 return &(cmb.triggers[idx]);
1060 }
1061 // Get the combo ID of the trigger pointed to by `ref` (usually ri->combotriggerref)
1062 dword get_combo_from_trigger_ref(dword ref)
1063 {
1064 dword cid = ref & 0x00FFFFFF;
1065 DCHECK(cid < MAXCOMBOS);
1066 return cid;
1067 }
1068
1069 ///------------------------------------------------//
1070 // Pointer Handling Functions //
1071 ///------------------------------------------------//
1072
1073 //LWeapon Helper
1074 class LwpnH : public SH
1075 {
1076
1077 public:
1078
1079
1080 static defWpnSprite getDefWeaponSprite(weapon *wp)
1081 {
1082 switch(wp->id)
1083 {
1084 case wNone: return ws_0;
1085 case wSword: return ws_0;
1086 case wBeam: return wsBeam;
1087 case wBrang : return wsBrang;
1088 case wBomb: return wsBomb;
1089 case wSBomb: return wsSBomb;
1090 case wLitBomb: return wsBombblast;
1091 case wLitSBomb: return wsBombblast;
1092 case wArrow: return wsArrow;
1093 case wRefArrow: return wsArrow;
1094 case wFire: return wsFire;
1095 case wRefFire: return wsFire;
1096 case wRefFire2: return wsFire;
1097 case wWhistle: return wsUnused45;
1098 case wBait: return wsBait;
1099 case wWand: return wsWandHandle;
1100 case wMagic: return wsMagic;
1101 case wCatching: return wsUnused45;
1102 case wWind: return wsWind;
1103 case wRefMagic: return wsRefMagic;
1104 case wRefFireball: return wsRefFireball;
1105 case wRefRock: return wsRock;
1106 case wHammer: return wsHammer;
1107 case wHookshot: return wsHookshotHead;
1108 case wHSHandle: return wsHookshotHandle;
1109 case wHSChain: return wsHookshotChainH;
1110 case wSSparkle: return wsSilverSparkle;
1111 case wFSparkle: return wsGoldSparkle;
1112 case wSmack: return wsHammerSmack;
1113 case wPhantom: return wsUnused45;
1114 case wCByrna: return wsByrnaCane;
1115 case wRefBeam: return wsRefBeam;
1116 case wStomp: return wsUnused45;
1117 case lwMax: return wsUnused45;
1118 case wScript1:
1119 case wScript2:
1120 case wScript3:
1121 case wScript4:
1122 case wScript5:
1123 case wScript6:
1124 case wScript7:
1125 case wScript8:
1126 case wScript9:
1127 case wScript10: return ws_0;
1128 case wIce: return wsIce; //new
1129 case wFlame: return wsEFire2; //new
1130 //not implemented; t/b/a
1131 case wSound:
1132 case wThrown:
1133 case wPot:
1134 case wLit:
1135 case wBombos:
1136 case wEther:
1137 case wQuake:
1138 case wSword180:
1139 case wSwordLA: return wsUnused45;
1140
1141 case ewFireball: return wsFireball2;
1142 case ewArrow: return wsEArrow;
1143 case ewBrang: return wsBrang;
1144 case ewSword: return wsEBeam;
1145 case ewRock: return wsRock;
1146 case ewMagic: return wsEMagic;
1147 case ewBomb: return wsEBomb;
1148 case ewSBomb: return wsESbomb;
1149 case ewLitBomb: return wsEBombblast;
1150 case ewLitSBomb: return wsESbombblast;
1151 case ewFireTrail: return wsEFiretrail;
1152 case ewFlame: return wsEFire;
1153 case ewWind: return wsEWind;
1154 case ewFlame2: return wsEFire2;
1155 case ewFlame2Trail: return wsEFiretrail2;
1156 case ewIce: return wsIce;
1157 case ewFireball2: return wsFireball2;
1158 default: return wsUnused45;
1159 }
1160 };
1161
1162 20064 static int32_t loadWeapon(const int32_t uid)
1163 {
1164 20064 tempweapon = ResolveSprite<weapon>(uid, "lweapon");
1165
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20064 times.
20064 if (!tempweapon)
1166 return _InvalidSpriteUID;
1167
1168 20064 return _NoError;
1169 20064 }
1170
1171 20064 static INLINE weapon *getWeapon()
1172 {
1173 20064 return tempweapon;
1174 }
1175
1176 37729 static INLINE void clearTemp()
1177 {
1178 37729 tempweapon = NULL;
1179 37729 }
1180
1181 private:
1182
1183 static weapon *tempweapon;
1184 };
1185
1186 weapon *LwpnH::tempweapon = NULL;
1187
1188 //EWeapon Helper
1189 class EwpnH : public SH
1190 {
1191
1192 public:
1193
1194 defWpnSprite getDefWeaponSprite(weapon *wp)
1195 {
1196 switch(wp->id)
1197 {
1198 case wNone: return ws_0;
1199 case wSword: return ws_0;
1200 case wBeam: return wsBeam;
1201 case wBrang : return wsBrang;
1202 case wBomb: return wsBomb;
1203 case wSBomb: return wsSBomb;
1204 case wLitBomb: return wsBombblast;
1205 case wLitSBomb: return wsBombblast;
1206 case wArrow: return wsArrow;
1207 case wRefArrow: return wsArrow;
1208 case wFire: return wsFire;
1209 case wRefFire: return wsFire;
1210 case wRefFire2: return wsFire;
1211 case wWhistle: return wsUnused45;
1212 case wBait: return wsBait;
1213 case wWand: return wsWandHandle;
1214 case wMagic: return wsMagic;
1215 case wCatching: return wsUnused45;
1216 case wWind: return wsWind;
1217 case wRefMagic: return wsRefMagic;
1218 case wRefFireball: return wsRefFireball;
1219 case wRefRock: return wsRock;
1220 case wHammer: return wsHammer;
1221 case wHookshot: return wsHookshotHead;
1222 case wHSHandle: return wsHookshotHandle;
1223 case wHSChain: return wsHookshotChainH;
1224 case wSSparkle: return wsSilverSparkle;
1225 case wFSparkle: return wsGoldSparkle;
1226 case wSmack: return wsHammerSmack;
1227 case wPhantom: return wsUnused45;
1228 case wCByrna: return wsByrnaCane;
1229 case wRefBeam: return wsRefBeam;
1230 case wStomp: return wsUnused45;
1231 case lwMax: return wsUnused45;
1232 case wScript1:
1233 case wScript2:
1234 case wScript3:
1235 case wScript4:
1236 case wScript5:
1237 case wScript6:
1238 case wScript7:
1239 case wScript8:
1240 case wScript9:
1241 case wScript10: return ws_0;
1242 case wIce: return wsIce; //new
1243 case wFlame: return wsEFire2; //new
1244 //not implemented; t/b/a
1245 case wSound:
1246 case wThrown:
1247 case wPot:
1248 case wLit:
1249 case wBombos:
1250 case wEther:
1251 case wQuake:
1252 case wSword180:
1253 case wSwordLA: return wsUnused45;
1254
1255 case ewFireball: return wsFireball2;
1256 case ewArrow: return wsEArrow;
1257 case ewBrang: return wsBrang;
1258 case ewSword: return wsEBeam;
1259 case ewRock: return wsRock;
1260 case ewMagic: return wsEMagic;
1261 case ewBomb: return wsEBomb;
1262 case ewSBomb: return wsESbomb;
1263 case ewLitBomb: return wsEBombblast;
1264 case ewLitSBomb: return wsESbombblast;
1265 case ewFireTrail: return wsEFiretrail;
1266 case ewFlame: return wsEFire;
1267 case ewWind: return wsEWind;
1268 case ewFlame2: return wsEFire2;
1269 case ewFlame2Trail: return wsEFiretrail2;
1270 case ewIce: return wsIce;
1271 case ewFireball2: return wsFireball2;
1272 default: return wsUnused45;
1273 }
1274 };
1275
1276 296065 static int32_t loadWeapon(const int32_t uid)
1277 {
1278 296065 tempweapon = ResolveSprite<weapon>(uid, "eweapon");
1279
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 296065 times.
296065 if (!tempweapon)
1280 return _InvalidSpriteUID;
1281
1282 296065 return _NoError;
1283 296065 }
1284
1285 296065 static INLINE weapon *getWeapon()
1286 {
1287 296065 return tempweapon;
1288 }
1289
1290 37729 static INLINE void clearTemp()
1291 {
1292 37729 tempweapon = NULL;
1293 37729 }
1294
1295 private:
1296
1297 static weapon *tempweapon;
1298 };
1299
1300 weapon *EwpnH::tempweapon = NULL;
1301
1302 37729 void clearScriptHelperData()
1303 {
1304 37729 GuyH::clearTemp();
1305 37729 LwpnH::clearTemp();
1306 37729 EwpnH::clearTemp();
1307 37729 ItemH::clearTemp();
1308 37729 }
1309 ////END HELPER FUNCTIONS
1310
1311 static int32_t numInstructions = 0; // Used to detect hangs
1312 static bool scriptCanSave = true;
1313
1314 764661899 static ScriptEngineData& get_script_engine_data(ScriptType type, int index)
1315 {
1316
8/8
✓ Branch 0 taken 730555136 times.
✓ Branch 1 taken 34106763 times.
✓ Branch 2 taken 730549850 times.
✓ Branch 3 taken 5286 times.
✓ Branch 4 taken 695550201 times.
✓ Branch 5 taken 34999649 times.
✓ Branch 6 taken 30042 times.
✓ Branch 7 taken 695520159 times.
764661899 if (type == ScriptType::DMap || type == ScriptType::OnMap || type == ScriptType::ScriptedPassiveSubscreen || type == ScriptType::ScriptedActiveSubscreen)
1317 {
1318 // `index` is used for dmapdataref, not for different script engine data.
1319 69141740 index = 0;
1320 69141740 }
1321
2/2
✓ Branch 0 taken 764529871 times.
✓ Branch 1 taken 132028 times.
764661899 if (type == ScriptType::EngineSubscreen)
1322 {
1323 // `index` is used for subscreendataref, not for different script engine data.
1324 132028 index = 0;
1325 132028 }
1326
1327 764661899 return scriptEngineDatas[{type, index}];
1328 }
1329
1330 1244710 static bool script_engine_data_exists(ScriptType type, int index)
1331 {
1332
6/8
✓ Branch 0 taken 1241030 times.
✓ Branch 1 taken 3680 times.
✓ Branch 2 taken 1241026 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 1241026 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1241026 times.
1244710 if (type == ScriptType::DMap || type == ScriptType::OnMap || type == ScriptType::ScriptedPassiveSubscreen || type == ScriptType::ScriptedActiveSubscreen)
1333 {
1334 // `index` is used for dmapdataref, not for different script engine data.
1335 3684 index = 0;
1336 3684 }
1337
1/2
✓ Branch 0 taken 1244710 times.
✗ Branch 1 not taken.
1244710 if (type == ScriptType::EngineSubscreen)
1338 {
1339 // `index` is used for subscreendataref, not for different script engine data.
1340 index = 0;
1341 }
1342
1343 1244710 return scriptEngineDatas.contains({type, index});
1344 }
1345
1346 65 static ScriptEngineData& get_script_engine_data(ScriptType type)
1347 {
1348 65 return get_script_engine_data(type, 0);
1349 }
1350
1351 440 void FFScript::clear_script_engine_data()
1352 {
1353 440 scriptEngineDatas.clear();
1354 440 }
1355
1356 714 void FFScript::clear_script_engine_data_for_continue()
1357 {
1358 // Generic scripts should survive F6->Continue!
1359
2/2
✓ Branch 0 taken 1489268 times.
✓ Branch 1 taken 714 times.
1489982 for (auto it = scriptEngineDatas.begin(); it != scriptEngineDatas.end();)
1360 {
1361
2/2
✓ Branch 0 taken 365568 times.
✓ Branch 1 taken 1123700 times.
1489268 if (it->first.first == ScriptType::Generic)
1362 365568 ++it;
1363 1123700 else it = scriptEngineDatas.erase(it);
1364 }
1365 714 }
1366
1367 2557128 void FFScript::reset_script_engine_data(ScriptType type, int index)
1368 {
1369 2557128 get_script_engine_data(type, index).reset();
1370 2557128 }
1371
1372 91293 void on_reassign_script_engine_data(ScriptType type, int index)
1373 {
1374 91293 auto& data = get_script_engine_data(type, index);
1375 91293 data.clear_ref();
1376 91293 FFScript::deallocateAllScriptOwned(type, index);
1377 91293 }
1378
1379 2032477 void FFScript::clear_script_engine_data(ScriptType type, int index)
1380 {
1381
4/8
✓ Branch 0 taken 2032477 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2032477 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2032477 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2032477 times.
2032477 if (type == ScriptType::DMap || type == ScriptType::OnMap || type == ScriptType::ScriptedPassiveSubscreen || type == ScriptType::ScriptedActiveSubscreen)
1382 {
1383 // `index` is used for dmapdataref, not for different script engine data.
1384 index = 0;
1385 }
1386
1/2
✓ Branch 0 taken 2032477 times.
✗ Branch 1 not taken.
2032477 if (type == ScriptType::EngineSubscreen)
1387 {
1388 // `index` is used for subscreendataref, not for different script engine data.
1389 index = 0;
1390 }
1391
1392 2032477 auto it = scriptEngineDatas.find({type, index});
1393
2/2
✓ Branch 0 taken 2032233 times.
✓ Branch 1 taken 244 times.
2032477 if (it != scriptEngineDatas.end())
1394 {
1395 244 scriptEngineDatas.erase(it);
1396 244 }
1397 2032477 }
1398
1399 142236 void FFScript::clear_script_engine_data_of_type(ScriptType type)
1400 {
1401 359278319 std::erase_if(scriptEngineDatas, [&](auto& kv) { return kv.first.first == type; });
1402 142236 }
1403
1404 refInfo& FFScript::ref(ScriptType type, int index)
1405 {
1406 return get_script_engine_data(type, index).ref;
1407 }
1408
1409 337 void FFScript::clear_ref(ScriptType type, int index)
1410 {
1411 337 get_script_engine_data(type, index).clear_ref();
1412 337 }
1413
1414 70836426 byte& FFScript::doscript(ScriptType type, int index)
1415 {
1416
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 70836426 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
70836426 if (type == ScriptType::Generic && unsigned(index) < NUMSCRIPTSGENERIC)
1417 return user_genscript::get(index).doscript();
1418 70836426 return get_script_engine_data(type, index).doscript;
1419 70836426 }
1420
1421 540109429 bool& FFScript::waitdraw(ScriptType type, int index)
1422 {
1423 540109429 return get_script_engine_data(type, index).waitdraw;
1424 }
1425
1426 34726448 static void set_current_script_engine_data(ScriptEngineData& data, ScriptType type, int script, int index)
1427 {
1428 34726448 bool got_initialized = false;
1429
1430 34726448 ri = &data.ref;
1431 34726448 stack = &data.stack;
1432 34726448 ret_stack = &data.ret_stack;
1433
1434 // By default, make `Screen->` refer to the top-left screen.
1435 // Will be set to something more specific for relevant script types.
1436 34726448 ri->screenref = cur_screen;
1437
1438
17/18
✗ Branch 0 not taken.
✓ Branch 1 taken 11734893 times.
✓ Branch 2 taken 111621 times.
✓ Branch 3 taken 1355297 times.
✓ Branch 4 taken 522434 times.
✓ Branch 5 taken 9695 times.
✓ Branch 6 taken 15569 times.
✓ Branch 7 taken 12324309 times.
✓ Branch 8 taken 6060311 times.
✓ Branch 9 taken 1542 times.
✓ Branch 10 taken 1330453 times.
✓ Branch 11 taken 125957 times.
✓ Branch 12 taken 909 times.
✓ Branch 13 taken 12244 times.
✓ Branch 14 taken 602613 times.
✓ Branch 15 taken 26364 times.
✓ Branch 16 taken 56336 times.
✓ Branch 17 taken 435901 times.
34726448 switch (type)
1439 {
1440 case ScriptType::FFC:
1441 {
1442 11734893 curscript = ffscripts[script];
1443 11734893 ffcdata* ffc = get_ffc(index);
1444
1445
2/2
✓ Branch 0 taken 11706439 times.
✓ Branch 1 taken 28454 times.
11734893 if (!data.initialized)
1446 {
1447 28454 got_initialized = true;
1448 28454 mapscr* scr = get_scr(ffc->screen_spawned);
1449 28454 memcpy(ri->d, scr->ffcs[index % 128].initd, 8 * sizeof(int32_t));
1450 28454 data.initialized = true;
1451 28454 }
1452
1453
2/2
✓ Branch 0 taken 2204466 times.
✓ Branch 1 taken 9530427 times.
11734893 ri->ffcref = ZScriptVersion::ffcRefIsSpriteId() ? ffc->getUID() : index;
1454 11734893 ri->screenref = ffc->screen_spawned;
1455 }
1456 11734893 break;
1457
1458 case ScriptType::NPC:
1459 {
1460 111621 enemy *spr = (enemy*)guys.getByUID(index);
1461 111621 curscript = guyscripts[script];
1462
1463
2/2
✓ Branch 0 taken 111449 times.
✓ Branch 1 taken 172 times.
111621 if (!data.initialized)
1464 {
1465 172 got_initialized = true;
1466 172 memcpy(ri->d, spr->initD, 8 * sizeof(int32_t));
1467 172 data.initialized = 1;
1468 172 }
1469
1470 111621 ri->npcref = index;
1471 111621 ri->screenref = spr->screen_spawned;
1472 }
1473 111621 break;
1474
1475 case ScriptType::Lwpn:
1476 {
1477 1355297 weapon *spr = (weapon*)Lwpns.getByUID(index);
1478 1355297 curscript = lwpnscripts[script];
1479
1480
2/2
✓ Branch 0 taken 1286496 times.
✓ Branch 1 taken 68801 times.
1355297 if (!data.initialized)
1481 {
1482 68801 got_initialized = true;
1483 68801 memcpy(ri->d, spr->initD, 8 * sizeof(int32_t));
1484 68801 data.initialized = 1;
1485 68801 }
1486
1487 1355297 ri->lwpnref = index;
1488 1355297 ri->screenref = spr->screen_spawned;
1489 }
1490 1355297 break;
1491
1492 case ScriptType::Ewpn:
1493 {
1494 522434 weapon *spr = (weapon*)Ewpns.getByUID(index);
1495 522434 curscript = ewpnscripts[script];
1496
1497
2/2
✓ Branch 0 taken 516683 times.
✓ Branch 1 taken 5751 times.
522434 if (!data.initialized)
1498 {
1499 5751 got_initialized = true;
1500 5751 memcpy(ri->d, spr->initD, 8 * sizeof(int32_t));
1501 5751 data.initialized = 1;
1502 5751 }
1503
1504 522434 ri->ewpnref = index;
1505 522434 ri->screenref = spr->screen_spawned;
1506 }
1507 522434 break;
1508
1509 case ScriptType::ItemSprite:
1510 {
1511 9695 item *spr = (item*)items.getByUID(index);
1512 9695 curscript = itemspritescripts[script];
1513
1514
2/2
✓ Branch 0 taken 9360 times.
✓ Branch 1 taken 335 times.
9695 if (!data.initialized)
1515 {
1516 335 got_initialized = true;
1517 335 memcpy(ri->d, spr->initD, 8 * sizeof(int32_t));
1518 335 data.initialized = 1;
1519 335 }
1520
1521 9695 ri->itemref = index;
1522 9695 ri->screenref = spr->screen_spawned;
1523 }
1524 9695 break;
1525
1526 case ScriptType::Item:
1527 {
1528 15569 int32_t i = index;
1529 15569 int32_t new_i = 0;
1530
2/2
✓ Branch 0 taken 337 times.
✓ Branch 1 taken 15232 times.
15569 bool collect = ( ( i < 1 ) || (i == COLLECT_SCRIPT_ITEM_ZERO) );
1531
3/4
✓ Branch 0 taken 337 times.
✓ Branch 1 taken 15232 times.
✓ Branch 2 taken 337 times.
✗ Branch 3 not taken.
15569 new_i = ( collect ) ? (( i != COLLECT_SCRIPT_ITEM_ZERO ) ? (i * -1) : 0) : i;
1532
1533 15569 curscript = itemscripts[script];
1534
1535
2/2
✓ Branch 0 taken 13490 times.
✓ Branch 1 taken 2079 times.
15569 if (!data.initialized)
1536 {
1537 2079 got_initialized = true;
1538
2/2
✓ Branch 0 taken 337 times.
✓ Branch 1 taken 1742 times.
2079 memcpy(ri->d, ( collect ) ? itemsbuf[new_i].initiald : itemsbuf[i].initiald, 8 * sizeof(int32_t));
1539 2079 data.initialized = true;
1540 2079 }
1541
2/2
✓ Branch 0 taken 337 times.
✓ Branch 1 taken 15232 times.
15569 ri->itemdataref = ( collect ) ? new_i : i; //'this' pointer
1542 }
1543 15569 break;
1544
1545 case ScriptType::Global:
1546 {
1547 12324309 curscript = globalscripts[script];
1548
2/2
✓ Branch 0 taken 12320994 times.
✓ Branch 1 taken 3315 times.
12324309 if (!data.initialized)
1549 {
1550 3315 got_initialized = true;
1551 3315 data.initialized = 1;
1552
1553 // If this compat QR is on, scripts can run before ~Init and set global variables.
1554 // Before overwriting them with 0, get rid of object references held by global variables.
1555
6/6
✓ Branch 0 taken 2673 times.
✓ Branch 1 taken 642 times.
✓ Branch 2 taken 1120 times.
✓ Branch 3 taken 1553 times.
✓ Branch 4 taken 19 times.
✓ Branch 5 taken 1101 times.
3315 if (get_qr(qr_OLD_INIT_SCRIPT_TIMING) && ZScriptVersion::gc() && script == GLOBAL_SCRIPT_INIT)
1556 {
1557
2/2
✓ Branch 0 taken 19456 times.
✓ Branch 1 taken 19 times.
19475 for (int i = 0; i < MAX_SCRIPT_REGISTERS; i++)
1558 19456 script_object_ref_dec(game->global_d[i]);
1559 19 }
1560 3315 }
1561 }
1562 12324309 break;
1563
1564 case ScriptType::Generic:
1565 {
1566 6060311 user_genscript& scr = user_genscript::get(script);
1567 6060311 curscript = genericscripts[script];
1568 6060311 scr.waitevent = false;
1569
2/2
✓ Branch 0 taken 6059630 times.
✓ Branch 1 taken 681 times.
6060311 if(!data.initialized)
1570 {
1571 681 got_initialized = true;
1572 681 scr.initd.copy_to(ri->d, 8);
1573 681 data.initialized = true;
1574 681 }
1575 6060311 ri->genericdataref = script;
1576 }
1577 6060311 break;
1578
1579 case ScriptType::GenericFrozen:
1580 {
1581 1542 user_genscript& scr = user_genscript::get(script);
1582 1542 curscript = genericscripts[script];
1583
2/2
✓ Branch 0 taken 1532 times.
✓ Branch 1 taken 10 times.
1542 if(!data.initialized)
1584 {
1585 10 got_initialized = true;
1586 10 scr.initd.copy_to(ri->d, 8);
1587 10 data.initialized = true;
1588 10 }
1589 1542 ri->genericdataref = script;
1590 }
1591 1542 break;
1592
1593 case ScriptType::Hero:
1594 {
1595 1330453 curscript = playerscripts[script];
1596 1330453 ri->screenref = Hero.current_screen;
1597
2/2
✓ Branch 0 taken 1329870 times.
✓ Branch 1 taken 583 times.
1330453 if (!data.initialized)
1598 {
1599 583 got_initialized = true;
1600 583 data.initialized = 1;
1601 583 }
1602 }
1603 1330453 break;
1604
1605 case ScriptType::DMap:
1606 {
1607 125957 curscript = dmapscripts[script];
1608 125957 ri->dmapdataref = index;
1609 //how do we clear initialised on dmap change?
1610
2/2
✓ Branch 0 taken 125827 times.
✓ Branch 1 taken 130 times.
125957 if ( !data.initialized )
1611 {
1612 130 got_initialized = true;
1613
2/2
✓ Branch 0 taken 1040 times.
✓ Branch 1 taken 130 times.
1170 for ( int32_t q = 0; q < 8; q++ )
1614 {
1615 1040 ri->d[q] = DMaps[ri->dmapdataref].initD[q];// * 10000;
1616 1040 }
1617 130 data.initialized = true;
1618 130 }
1619 }
1620 125957 break;
1621
1622 case ScriptType::OnMap:
1623 {
1624 909 curscript = dmapscripts[script];
1625 909 ri->dmapdataref = index;
1626
2/2
✓ Branch 0 taken 902 times.
✓ Branch 1 taken 7 times.
909 if (!data.initialized)
1627 {
1628 7 got_initialized = true;
1629
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 7 times.
63 for ( int32_t q = 0; q < 8; q++ )
1630 {
1631 56 ri->d[q] = DMaps[ri->dmapdataref].onmap_initD[q];
1632 56 }
1633 7 data.initialized = true;
1634 7 }
1635 }
1636 909 break;
1637
1638 case ScriptType::ScriptedActiveSubscreen:
1639 {
1640 12244 curscript = dmapscripts[script];
1641 12244 ri->dmapdataref = index;
1642
2/2
✓ Branch 0 taken 12203 times.
✓ Branch 1 taken 41 times.
12244 if (!data.initialized)
1643 {
1644 41 got_initialized = true;
1645
2/2
✓ Branch 0 taken 328 times.
✓ Branch 1 taken 41 times.
369 for ( int32_t q = 0; q < 8; q++ )
1646 {
1647 328 ri->d[q] = DMaps[ri->dmapdataref].sub_initD[q];
1648 328 }
1649 41 data.initialized = true;
1650 41 }
1651 }
1652 12244 break;
1653
1654 case ScriptType::ScriptedPassiveSubscreen:
1655 {
1656 602613 curscript = dmapscripts[script];
1657 602613 ri->dmapdataref = index;
1658
2/2
✓ Branch 0 taken 602243 times.
✓ Branch 1 taken 370 times.
602613 if (!data.initialized)
1659 {
1660 370 got_initialized = true;
1661
2/2
✓ Branch 0 taken 2960 times.
✓ Branch 1 taken 370 times.
3330 for ( int32_t q = 0; q < 8; q++ )
1662 {
1663 2960 ri->d[q] = DMaps[ri->dmapdataref].sub_initD[q];
1664 2960 }
1665 370 data.initialized = true;
1666 370 }
1667 }
1668 602613 break;
1669 case ScriptType::EngineSubscreen:
1670 {
1671 26364 curscript = subscreenscripts[script];
1672 26364 ri->subscreendataref = get_subref(-1, index);
1673 27092 auto [ptr,_ty] = load_subdata(ri->subscreendataref);
1674
1675
3/4
✓ Branch 0 taken 26364 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26273 times.
✓ Branch 3 taken 91 times.
26364 if (ptr && !data.initialized)
1676 {
1677 91 got_initialized = true;
1678
2/2
✓ Branch 0 taken 728 times.
✓ Branch 1 taken 91 times.
819 for ( int32_t q = 0; q < 8; q++ )
1679 {
1680 728 ri->d[q] = ptr->initd[q];
1681 728 }
1682 91 data.initialized = true;
1683 91 }
1684 }
1685 26364 break;
1686
1687 case ScriptType::Screen:
1688 {
1689 56336 curscript = screenscripts[script];
1690
1691
2/2
✓ Branch 0 taken 56192 times.
✓ Branch 1 taken 144 times.
56336 if (!data.initialized)
1692 {
1693 144 got_initialized = true;
1694 144 mapscr* scr = get_scr(index);
1695
2/2
✓ Branch 0 taken 1152 times.
✓ Branch 1 taken 144 times.
1296 for ( int32_t q = 0; q < 8; q++ )
1696 {
1697 1152 ri->d[q] = scr->screeninitd[q];// * 10000;
1698 1152 }
1699 144 data.initialized = true;
1700 144 }
1701
1702 56336 ri->screenref = index;
1703 }
1704 56336 break;
1705
1706 case ScriptType::Combo:
1707 {
1708 435901 curscript = comboscripts[script];
1709
1710 435901 rpos_t rpos = combopos_ref_to_rpos(index);
1711 435901 int32_t lyr = combopos_ref_to_layer(index);
1712 435901 auto rpos_handle = get_rpos_handle(rpos, lyr);
1713 435901 int32_t id = rpos_handle.data();
1714
2/2
✓ Branch 0 taken 421019 times.
✓ Branch 1 taken 14882 times.
435901 if (!data.initialized)
1715 {
1716 14882 got_initialized = true;
1717 14882 memset(ri->d, 0, 8 * sizeof(int32_t));
1718
2/2
✓ Branch 0 taken 119056 times.
✓ Branch 1 taken 14882 times.
133938 for ( int32_t q = 0; q < 8; q++ )
1719 119056 ri->d[q] = combobuf[id].initd[q];
1720 14882 data.initialized = true;
1721 14882 }
1722
1723 435901 ri->combodataref = id; //'this' pointer
1724 435901 ri->comboposref = index; //used for X(), Y(), Layer(), and so forth.
1725 435901 ri->screenref = rpos_handle.screen;
1726 435901 break;
1727 }
1728 }
1729
1730
2/2
✓ Branch 0 taken 34600602 times.
✓ Branch 1 taken 125846 times.
34726448 if (got_initialized)
1731 125846 ri->pc = curscript->pc;
1732 34726448 }
1733
1734 643321730 ffcdata* ResolveFFCWithID(ffc_id_t id)
1735 {
1736
2/2
✓ Branch 0 taken 231 times.
✓ Branch 1 taken 643321499 times.
643321730 if (BC::checkFFC(id) != SH::_NoError)
1737 231 return nullptr;
1738
1739 643321499 ffcdata* ffc = get_ffc(id);
1740
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 643321499 times.
643321499 if (!ffc)
1741 scripting_log_error_with_context("Invalid ffc using ID = {}", id);
1742
1743 643321499 return ffc;
1744 643321730 }
1745
1746 646381308 static ffcdata *ResolveFFC(int32_t ffcref)
1747 {
1748
2/2
✓ Branch 0 taken 6428965 times.
✓ Branch 1 taken 639952343 times.
646381308 if (ZScriptVersion::ffcRefIsSpriteId())
1749 6428965 return ResolveSprite<ffcdata>(ffcref, "ffc");
1750
1751 639952343 return ResolveFFCWithID(ffcref);
1752 646381308 }
1753
1754 568164 static mapscr* ResolveMapdataScr(int32_t mapdataref)
1755 {
1756 568164 auto mapdata = decode_mapdata_ref(mapdataref);
1757
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 568164 times.
568164 if (!mapdata.scr)
1758 scripting_log_error_with_context("mapdata id is invalid: {}", mapdataref);
1759 568164 return mapdata.scr;
1760 }
1761
1762 static rpos_handle_t ResolveMapdataPos(int32_t mapdataref, int pos)
1763 {
1764 auto mapdata = decode_mapdata_ref(mapdataref);
1765 if (!mapdata.scr)
1766 {
1767 scripting_log_error_with_context("mapdata id is invalid: {}", mapdataref);
1768 return rpos_handle_t{};
1769 }
1770
1771 return mapdata.resolve_pos(pos);
1772 }
1773
1774 127396572 int mapdata::max_pos()
1775 {
1776
2/2
✓ Branch 0 taken 95534503 times.
✓ Branch 1 taken 31862069 times.
127396572 if (type == mapdata_type::TemporaryCurrentRegion)
1777 95534503 return (int)region_max_rpos;
1778
1779
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31862069 times.
31862069 if (type == mapdata_type::TemporaryScrollingRegion)
1780 return (int)scrolling_region.screen_count * 176 - 1;
1781
1782 31862069 return 175;
1783 127396572 }
1784
1785 127396572 rpos_handle_t mapdata::resolve_pos(int pos)
1786 {
1787
3/4
✓ Branch 0 taken 121655856 times.
✓ Branch 1 taken 5740716 times.
✓ Branch 2 taken 121655856 times.
✗ Branch 3 not taken.
127396572 if (!screenscrolling && scrolling())
1788 {
1789 int32_t mapdataref = create_mapdata_temp_ref(type, screen, layer);
1790 scripting_log_error_with_context("mapdata id is invalid: {} - screen is not scrolling right now", mapdataref);
1791 return rpos_handle_t{};
1792 }
1793
1794 // mapdata loaded via `Game->LoadTempScreen(layer)` have access to the entire region.
1795
2/2
✓ Branch 0 taken 95534503 times.
✓ Branch 1 taken 31862069 times.
127396572 if (type == mapdata_type::TemporaryCurrentRegion)
1796 {
1797 95534503 rpos_t rpos = (rpos_t)pos;
1798
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 95534503 times.
95534503 if (BC::checkComboRpos(rpos) != SH::_NoError)
1799 return rpos_handle_t{};
1800
1801 95534503 return get_rpos_handle(rpos, layer);
1802 }
1803
1804 // mapdata loaded via `Game->LoadScrollingScreen(layer)` have access to the entire scrolling region.
1805
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31862069 times.
31862069 if (type == mapdata_type::TemporaryScrollingRegion)
1806 {
1807 rpos_t rpos = (rpos_t)pos;
1808 rpos_t max = (rpos_t)(scrolling_region.screen_count * 176 - 1);
1809 if (BC::checkBoundsRpos(rpos, (rpos_t)0, max) != SH::_NoError)
1810 return rpos_handle_t{};
1811
1812 return {base_scr, scr, scr->screen, layer, rpos, RPOS_TO_POS(rpos)};
1813 }
1814
1815 // Otherwise, access is limited to just one screen.
1816
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31862069 times.
31862069 if (BC::checkComboPos(pos) != SH::_NoError)
1817 return rpos_handle_t{};
1818
1819
1/2
✓ Branch 0 taken 31862069 times.
✗ Branch 1 not taken.
31862069 if (type == mapdata_type::CanonicalScreen)
1820 31862069 return {base_scr, scr, screen, 0, (rpos_t)pos, pos};
1821
1822 if (scrolling())
1823 {
1824 if (!scr->is_valid())
1825 return rpos_handle_t{};
1826
1827 return {base_scr, scr, screen, layer, (rpos_t)pos, pos};
1828 }
1829
1830 rpos_t rpos = POS_TO_RPOS(pos, screen);
1831 if (BC::checkComboRpos(rpos) != SH::_NoError)
1832 return rpos_handle_t{};
1833
1834 return {base_scr, scr, screen, layer, rpos, pos};
1835 127396572 }
1836
1837 3023863 ffc_handle_t mapdata::resolve_ffc_handle(int index)
1838 {
1839 3023863 index -= 1;
1840
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3023863 times.
3023863 if (BC::checkMapdataFFC(index) != SH::_NoError)
1841 return ffc_handle_t{};
1842
1843 3023863 int screen_index_offset = 0;
1844
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3023863 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3023863 if (current() && layer == 0)
1845 screen_index_offset = get_region_screen_offset(screen);
1846
1847 3023863 return *scr->getFFCHandle(index, screen_index_offset);
1848 3023863 }
1849
1850 ffcdata* mapdata::resolve_ffc(int index)
1851 {
1852 return resolve_ffc_handle(index).ffc;
1853 }
1854
1855 2045 static ffc_handle_t ResolveMapdataFFC(int32_t mapdataref, int index)
1856 {
1857 2045 index -= 1;
1858
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2045 times.
2045 if (BC::checkMapdataFFC(index) != SH::_NoError)
1859 return ffc_handle_t{};
1860
1861 2045 auto result = decode_mapdata_ref(mapdataref);
1862
1/2
✓ Branch 0 taken 2045 times.
✗ Branch 1 not taken.
2045 if (!result.scr)
1863 {
1864 scripting_log_error_with_context("mapdata id is invalid: {}", mapdataref);
1865 return ffc_handle_t{};
1866 }
1867
1868 2045 int screen_index_offset = 0;
1869
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2045 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2045 if (result.current() && result.layer == 0)
1870 screen_index_offset = get_region_screen_offset(result.screen);
1871
1872 2045 return *result.scr->getFFCHandle(index, screen_index_offset);
1873 2045 }
1874
1875 int32_t genscript_timing = SCR_TIMING_START_FRAME;
1876 static word max_valid_genscript;
1877
1878 225280 void user_genscript::clear()
1879 {
1880 225280 wait_atleast = true;
1881 225280 waituntil = SCR_TIMING_START_FRAME;
1882 225280 waitevent = false;
1883 225280 exitState = 0;
1884 225280 reloadState = 0;
1885 225280 eventstate = 0;
1886 225280 initd.clear();
1887 225280 data.clear();
1888 225280 quit();
1889 225280 }
1890 637 void user_genscript::launch()
1891 {
1892 637 quit();
1893 637 doscript() = true;
1894 637 wait_atleast = true;
1895 637 waituntil = SCR_TIMING_START_FRAME;
1896 637 waitevent = false;
1897 637 }
1898 225968 void user_genscript::quit()
1899 {
1900
1/2
✓ Branch 0 taken 225968 times.
✗ Branch 1 not taken.
225968 if(indx > -1)
1901 {
1902 225968 FFCore.destroyScriptableObject(ScriptType::Generic, indx);
1903 225968 }
1904 225968 _doscript = false;
1905 225968 }
1906 426857976 byte& user_genscript::doscript()
1907 {
1908 426857976 return _doscript;
1909 }
1910 512 byte const& user_genscript::doscript() const
1911 {
1912 512 return _doscript;
1913 }
1914
1915
1916 449396292 user_genscript& user_genscript::get(int ind)
1917 {
1918
3/4
✓ Branch 0 taken 449395851 times.
✓ Branch 1 taken 441 times.
✓ Branch 2 taken 449395851 times.
✗ Branch 3 not taken.
449396292 if(ind < 1 || ind >= NUMSCRIPTSGENERIC)
1919 441 ind = 0;
1920 449396292 user_scripts[ind].indx = ind;
1921 449396292 return user_scripts[ind];
1922 }
1923
3/4
✓ Branch 0 taken 220160 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 219730 times.
✓ Branch 3 taken 430 times.
220160 user_genscript user_genscript::user_scripts[NUMSCRIPTSGENERIC];
1924
1925 1594 void countGenScripts()
1926 {
1927 1594 max_valid_genscript = 0;
1928
2/2
✓ Branch 0 taken 814534 times.
✓ Branch 1 taken 1594 times.
816128 for(auto q = 1; q < NUMSCRIPTSGENERIC; ++q)
1929 {
1930
3/4
✓ Branch 0 taken 814534 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 809421 times.
✓ Branch 3 taken 5113 times.
814534 if(genericscripts[q] && genericscripts[q]->valid())
1931 5113 max_valid_genscript = q;
1932 814534 }
1933 1594 }
1934 46605 void timeExitAllGenscript(byte exState)
1935 {
1936
2/2
✓ Branch 0 taken 42702 times.
✓ Branch 1 taken 46605 times.
89307 for(auto q = 1; q <= max_valid_genscript; ++q)
1937 42702 user_genscript::get(q).timeExit(exState);
1938 46605 }
1939 500388 void throwGenScriptEvent(int32_t event)
1940 {
1941
2/2
✓ Branch 0 taken 275698 times.
✓ Branch 1 taken 500388 times.
776086 for(auto q = 1; q <= max_valid_genscript; ++q)
1942 {
1943 275698 user_genscript& scr = user_genscript::get(q);
1944
2/2
✓ Branch 0 taken 177127 times.
✓ Branch 1 taken 98571 times.
275698 if(!scr.doscript()) continue;
1945
2/2
✓ Branch 0 taken 151399 times.
✓ Branch 1 taken 25728 times.
177127 if(!genericscripts[q]->valid()) continue;
1946
2/2
✓ Branch 0 taken 50129 times.
✓ Branch 1 taken 101270 times.
151399 if(!scr.waitevent) continue;
1947
2/2
✓ Branch 0 taken 3418 times.
✓ Branch 1 taken 46711 times.
50129 if(scr.eventstate & (1<<event))
1948 {
1949 3418 auto& data = get_script_engine_data(ScriptType::Generic, q);
1950 3418 data.ref.d[rEXP1] = event*10000;
1951 3418 scr.waitevent = false;
1952
1953 //Run the script!
1954 3418 ZScriptVersion::RunScript(ScriptType::Generic, q, q);
1955 3418 }
1956 50129 }
1957 500388 }
1958
1959 226 void load_genscript(const gamedata& gd)
1960 {
1961
2/2
✓ Branch 0 taken 115712 times.
✓ Branch 1 taken 226 times.
115938 for(size_t q = 0; q < NUMSCRIPTSGENERIC; ++q)
1962 {
1963 115712 user_genscript& gen = user_genscript::get(q);
1964 115712 gen.clear();
1965 115712 gen.doscript() = gd.gen_doscript.get(q);
1966 115712 gen.exitState = gd.gen_exitState[q];
1967 115712 gen.reloadState = gd.gen_reloadState[q];
1968 115712 gen.eventstate = gd.gen_eventstate[q];
1969 115712 gen.initd = gd.gen_initd[q];
1970 115712 gen.data = gd.gen_data[q];
1971 115712 }
1972 226 }
1973 214 void load_genscript(const zinitdata& zd)
1974 {
1975
2/2
✓ Branch 0 taken 109568 times.
✓ Branch 1 taken 214 times.
109782 for(size_t q = 0; q < NUMSCRIPTSGENERIC; ++q)
1976 {
1977 109568 user_genscript& gen = user_genscript::get(q);
1978 109568 gen.clear();
1979 109568 gen.doscript() = zd.gen_doscript.get(q);
1980 109568 gen.exitState = zd.gen_exitState[q];
1981 109568 gen.reloadState = zd.gen_reloadState[q];
1982 109568 gen.eventstate = zd.gen_eventstate[q];
1983 109568 gen.initd = zd.gen_initd[q];
1984 109568 gen.data = zd.gen_data[q];
1985 109568 }
1986 214 }
1987
1988 1 void save_genscript(gamedata& gd)
1989 {
1990
2/2
✓ Branch 0 taken 512 times.
✓ Branch 1 taken 1 times.
513 for(size_t q = 0; q < NUMSCRIPTSGENERIC; ++q)
1991 {
1992 512 user_genscript const& gen = user_genscript::get(q);
1993 512 gd.gen_doscript.set(q, gen.doscript());
1994 512 gd.gen_exitState[q] = gen.exitState;
1995 512 gd.gen_reloadState[q] = gen.reloadState;
1996 512 gd.gen_eventstate[q] = gen.eventstate;
1997 512 gd.gen_initd[q] = gen.initd;
1998 512 gd.gen_data[q] = gen.data;
1999 512 }
2000 1 }
2001
2002 628519916 void FFScript::runGenericPassiveEngine(int32_t scrtm)
2003 {
2004
2/2
✓ Branch 0 taken 45195711 times.
✓ Branch 1 taken 583324205 times.
628519916 if(!max_valid_genscript) return; //No generic scripts in the quest!
2005 45195711 bool init = (scrtm == SCR_TIMING_INIT);
2006
2/2
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 45195582 times.
45195711 if(!init)
2007 {
2008
2/2
✓ Branch 0 taken 882029 times.
✓ Branch 1 taken 44313553 times.
45195582 if(genscript_timing != scrtm)
2009 {
2010
2/2
✓ Branch 0 taken 3911161 times.
✓ Branch 1 taken 882029 times.
4793190 while(genscript_timing != scrtm)
2011 3911161 runGenericPassiveEngine(genscript_timing);
2012 882029 }
2013 45195582 }
2014
2/2
✓ Branch 0 taken 426306104 times.
✓ Branch 1 taken 45195711 times.
471501815 for(auto q = 1; q <= max_valid_genscript; ++q)
2015 {
2016 426306104 user_genscript& scr = user_genscript::get(q);
2017
2/2
✓ Branch 0 taken 246929884 times.
✓ Branch 1 taken 179376220 times.
426306104 if(!scr.doscript()) continue;
2018
2/2
✓ Branch 0 taken 28899477 times.
✓ Branch 1 taken 218030407 times.
246929884 if(!genericscripts[q]->valid()) continue;
2019
2/2
✓ Branch 0 taken 89025562 times.
✓ Branch 1 taken 129004845 times.
218030407 if(scr.waitevent) continue;
2020
8/8
✓ Branch 0 taken 129004750 times.
✓ Branch 1 taken 95 times.
✓ Branch 2 taken 103603910 times.
✓ Branch 3 taken 25400840 times.
✓ Branch 4 taken 103603324 times.
✓ Branch 5 taken 586 times.
✓ Branch 6 taken 97547110 times.
✓ Branch 7 taken 6056214 times.
129004845 if(!init && (scr.waituntil > scrtm || (!scr.wait_atleast && scr.waituntil != scrtm)))
2021 122947950 continue;
2022
2023 //Run the script!
2024 6056895 ZScriptVersion::RunScript(ScriptType::Generic, q, q);
2025 6056895 }
2026
4/4
✓ Branch 0 taken 45195582 times.
✓ Branch 1 taken 129 times.
✓ Branch 2 taken 44037020 times.
✓ Branch 3 taken 1158562 times.
45195711 if(init || genscript_timing >= SCR_TIMING_END_FRAME)
2027 1158691 genscript_timing = SCR_TIMING_START_FRAME;
2028 44037020 else ++genscript_timing;
2029 628519916 }
2030
2031 14496 void FFScript::initZScriptDMapScripts()
2032 {
2033
1/2
✓ Branch 0 taken 14496 times.
✗ Branch 1 not taken.
14496 scriptEngineDatas[{ScriptType::DMap, 0}] = ScriptEngineData();
2034
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14496 times.
14496 scriptEngineDatas[{ScriptType::ScriptedPassiveSubscreen, 0}] = ScriptEngineData();
2035 14496 }
2036
2037 1439 void FFScript::initZScriptSubscreenScript()
2038 {
2039
1/2
✓ Branch 0 taken 1439 times.
✗ Branch 1 not taken.
1439 scriptEngineDatas[{ScriptType::EngineSubscreen, 0}] = ScriptEngineData();
2040 1439 }
2041 14426 void FFScript::initZScriptScriptedActiveSubscreen()
2042 {
2043
1/2
✓ Branch 0 taken 14426 times.
✗ Branch 1 not taken.
14426 scriptEngineDatas[{ScriptType::ScriptedActiveSubscreen, 0}] = ScriptEngineData();
2044 14426 }
2045
2046 7 void FFScript::initZScriptOnMapScript()
2047 {
2048
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 scriptEngineDatas[{ScriptType::OnMap, 0}] = ScriptEngineData();
2049 7 }
2050
2051 2915 void FFScript::initZScriptHeroScripts()
2052 {
2053
1/2
✓ Branch 0 taken 2915 times.
✗ Branch 1 not taken.
2915 scriptEngineDatas[{ScriptType::Hero, 0}] = ScriptEngineData();
2054 2915 }
2055
2056 2567 void FFScript::initZScriptItemScripts()
2057 {
2058
2/2
✓ Branch 0 taken 657152 times.
✓ Branch 1 taken 2567 times.
659719 for ( int32_t q = 0; q < 256; q++ )
2059 {
2060 657152 auto& data = get_script_engine_data(ScriptType::Item, q);
2061 657152 data.reset();
2062
2/2
✓ Branch 0 taken 657085 times.
✓ Branch 1 taken 67 times.
657152 data.doscript = (itemsbuf[q].flags&item_passive_script) && game->item[q];
2063 657152 }
2064
2065
2/2
✓ Branch 0 taken 657152 times.
✓ Branch 1 taken 2567 times.
659719 for ( int32_t q = -256; q < 0; q++ )
2066 {
2067 657152 auto& data = get_script_engine_data(ScriptType::Item, q);
2068 657152 data.reset();
2069 657152 data.doscript = 0;
2070 657152 }
2071 2567 }
2072
2073 3449923 int get_mouse_state(int index)
2074 {
2075 3449923 int value = 0;
2076
1/2
✓ Branch 0 taken 3449923 times.
✗ Branch 1 not taken.
3449923 if (replay_is_replaying())
2077 {
2078 3449923 value = replay_get_mouse(index);
2079 3449923 }
2080 else if (index == 0)
2081 {
2082 value = script_mouse_x;
2083 }
2084 else if (index == 1)
2085 {
2086 value = script_mouse_y;
2087 }
2088 else if (index == 2)
2089 {
2090 value = script_mouse_z;
2091 }
2092 else if (index == 3)
2093 {
2094 value = script_mouse_b;
2095 }
2096
2097
2/2
✓ Branch 0 taken 3448327 times.
✓ Branch 1 taken 1596 times.
3449923 if (replay_is_recording())
2098 {
2099 1596 replay_set_mouse(index, value);
2100 1596 }
2101
2102 3449923 return value;
2103 }
2104
2105 ///---------------------------------------------//
2106 // Array Helper Functions //
2107 ///---------------------------------------------//
2108
2109 303090259 size_t ArrayH::getSize(const int32_t ptr)
2110 {
2111 303090259 ArrayManager am(ptr);
2112 303090259 return am.size();
2113 }
2114
2115 //Can't you get the std::string and then check its length?
2116 int32_t ArrayH::strlen(const int32_t ptr)
2117 {
2118 ArrayManager am(ptr);
2119 if (am.invalid() || am.size() == 0)
2120 return -1;
2121
2122 word count;
2123 size_t sz = am.size();
2124 for(count = 0; BC::checkUserArrayIndex(count, sz) == _NoError
2125 && am.get(count) != '\0'; count++);
2126
2127 return count;
2128 }
2129
2130 //Returns values of a zscript array as an std::string.
2131 12284614 void ArrayH::getString(const int32_t ptr, string &str, dword num_chars, dword offset)
2132 {
2133 12284614 ArrayManager am(ptr);
2134
2135
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 12284609 times.
12284614 if(am.invalid())
2136 {
2137 5 str.clear();
2138 5 return;
2139 }
2140
2141 12284609 str.clear();
2142 12284609 size_t sz = am.size();
2143
5/6
✓ Branch 0 taken 174004629 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12284609 times.
✓ Branch 3 taken 161720020 times.
✓ Branch 4 taken 12284609 times.
✓ Branch 5 taken 161720020 times.
174004629 for(word i = offset; BC::checkUserArrayIndex(i, sz) == _NoError && am.get(i) != '\0' && num_chars != 0; i++)
2144 {
2145 161720020 int32_t c = am.get(i) / 10000;
2146
1/2
✓ Branch 0 taken 161720020 times.
✗ Branch 1 not taken.
161720020 if(byte(c) != c)
2147 {
2148 Z_scripterrlog("Illegal char value (%d) at position [%d] in string pointer %d\n", c, i, ptr);
2149 Z_scripterrlog("Value of invalid char will overflow.\n");
2150 }
2151 161720020 str += byte(c);
2152 161720020 --num_chars;
2153 161720020 }
2154 12284614 }
2155
2156 //Used for issues where reading the ZScript array floods the console with errors 'Accessing array index [12] size of 12.
2157 //Happens with Quad3D and some other functions, and I have no clue why. -Z ( 28th April, 2019 )
2158 //Like getString but for an array of longs instead of chars. *(arrayPtr is not checked for validity)
2159 void ArrayH::getValues2(const int32_t ptr, int32_t* arrayPtr, dword num_values, dword offset) //a hack -Z
2160 {
2161 ArrayManager am(ptr);
2162
2163 if(am.invalid())
2164 return;
2165
2166 size_t sz = am.size();
2167 for(word i = offset; BC::checkUserArrayIndex(i, sz+1) == _NoError && num_values != 0; i++)
2168 {
2169 arrayPtr[i] = (am.get(i) / 10000);
2170 num_values--;
2171 }
2172 }
2173
2174 //Like getString but for an array of longs instead of chars. *(arrayPtr is not checked for validity)
2175 1080 void ArrayH::getValues(const int32_t ptr, int32_t* arrayPtr, dword num_values, dword offset)
2176 {
2177 1080 ArrayManager am(ptr);
2178
2179
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1080 times.
1080 if (am.invalid())
2180 return;
2181 1080 size_t sz = am.size();
2182
4/4
✓ Branch 0 taken 1080 times.
✓ Branch 1 taken 12960 times.
✓ Branch 2 taken 1080 times.
✓ Branch 3 taken 12960 times.
14040 for(word i = offset; num_values != 0 && BC::checkUserArrayIndex(i, sz) == _NoError; i++)
2183 {
2184 12960 arrayPtr[i] = (am.get(i) / 10000);
2185 12960 num_values--;
2186 12960 }
2187 1080 }
2188
2189 2 void ArrayH::copyValues(const int32_t ptr, const int32_t ptr2)
2190 {
2191 2 ArrayManager am1(ptr), am2(ptr2);
2192
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 if(am1.invalid() || am2.invalid())
2193 return;
2194
2195 2 int sz = std::min(am1.size(),am2.size());
2196
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 for (int i = 0; i < sz; i++)
2197 {
2198 4 am1.set(i,am2.get(i));
2199 4 }
2200 2 }
2201 //Get element from array
2202 1442196532 INLINE int32_t ArrayH::getElement(const int32_t ptr, int32_t offset, const bool neg)
2203 {
2204 1442196532 ArrayManager am(ptr,neg);
2205 1442196532 return am.get(offset);
2206 }
2207
2208 //Set element in array
2209 676731370 INLINE void ArrayH::setElement(const int32_t ptr, int32_t offset, const int32_t value, const bool neg, const script_object_type type)
2210 {
2211 676731370 ArrayManager am(ptr,neg);
2212 676731370 am.set(offset, value, type);
2213 676731370 }
2214
2215 3297055 int32_t ArrayH::setArray(const int32_t ptr, string const& s2, bool resize)
2216 {
2217 3297055 ArrayManager am(ptr);
2218
2219
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3297055 times.
3297055 if (am.invalid())
2220 return _InvalidPointer;
2221
2222 size_t i;
2223
2224
3/4
✓ Branch 0 taken 3297055 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3268521 times.
✓ Branch 3 taken 28534 times.
3297055 if(am.can_resize() && resize)
2225 28534 am.resize_min(s2.size()+1);
2226
2227 3297055 size_t sz = am.size();
2228
2/2
✓ Branch 0 taken 44038604 times.
✓ Branch 1 taken 3297055 times.
47335659 for(i = 0; i < s2.size(); i++)
2229 {
2230
1/2
✓ Branch 0 taken 44038604 times.
✗ Branch 1 not taken.
44038604 if(i >= sz)
2231 {
2232 am.set(sz-1,'\0');
2233 return _Overflow;
2234 }
2235
2236
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44038604 times.
44038604 if(BC::checkUserArrayIndex(i, sz) == _NoError)
2237 44038604 am.set(i,s2[i] * 10000);
2238 44038604 }
2239
2240
1/2
✓ Branch 0 taken 3297055 times.
✗ Branch 1 not taken.
3297055 if(BC::checkUserArrayIndex(i, sz) == _NoError)
2241 3297055 am.set(i,'\0');
2242
2243 3297055 return _NoError;
2244 3297055 }
2245
2246 1182534 void FFScript::release_sprite_owned_objects(int32_t sprite_id)
2247 {
2248 1182534 std::vector<uint32_t> ids_to_clear;
2249
8/14
✓ Branch 0 taken 1182534 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1182534 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1182534 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 37084171 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 35901637 times.
✓ Branch 9 taken 1182534 times.
✓ Branch 10 taken 35901637 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 35901637 times.
✗ Branch 13 not taken.
37084171 for (auto& script_object : script_objects | std::views::values)
2250 {
2251
3/4
✓ Branch 0 taken 35901637 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3948 times.
✓ Branch 3 taken 35897689 times.
35901637 if (script_object->sprite_own_clear(sprite_id))
2252 {
2253
1/2
✓ Branch 0 taken 3948 times.
✗ Branch 1 not taken.
3948 ids_to_clear.push_back(script_object->id);
2254
1/2
✓ Branch 0 taken 3948 times.
✗ Branch 1 not taken.
3948 script_object->disown();
2255 3948 }
2256 }
2257
2258
3/4
✓ Branch 0 taken 1182534 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 504270 times.
✓ Branch 3 taken 678264 times.
1182534 if (ZScriptVersion::gc())
2259 {
2260
2/2
✓ Branch 0 taken 3948 times.
✓ Branch 1 taken 504270 times.
508218 for (auto id : ids_to_clear)
2261
1/2
✓ Branch 0 taken 3948 times.
✗ Branch 1 not taken.
3948 script_object_ref_dec(id);
2262 504270 }
2263 else
2264 {
2265
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 678264 times.
678264 for (auto id : ids_to_clear)
2266 delete_script_object(id);
2267 }
2268
2269
3/4
✓ Branch 0 taken 1182534 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 503402 times.
✓ Branch 3 taken 679132 times.
1182534 if (!ZScriptVersion::gc_arrays())
2270 {
2271
2/2
✓ Branch 0 taken 2781045540 times.
✓ Branch 1 taken 679132 times.
2781724672 for (int32_t i = 1; i < NUM_ZSCRIPT_ARRAYS; i++)
2272 {
2273
2/4
✓ Branch 0 taken 2781045540 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2781045540 times.
2781045540 if (arrayOwner[i].sprite_own_clear(sprite_id))
2274 FFScript::deallocateArray(i);
2275 2781045540 }
2276 679132 }
2277 1182534 }
2278
2279 // Called when the sprite object is being destroyed.
2280 //
2281 // - clears any object references retained by a sprite via "ownership".
2282 // See the comment above user_abstract_obj::set_owned_by_script for more.
2283 // - clears script engine data
2284 // - invalidates any internal array references that refer to this sprite
2285 1178999 void FFScript::destroySprite(sprite* sprite)
2286 {
2287 DCHECK(sprite->get_scrtype().has_value());
2288 1178999 ScriptType scriptType = *sprite->get_scrtype();
2289 1178999 int32_t uid = sprite->getUID();
2290 1178999 FFCore.release_sprite_owned_objects(uid);
2291 1178999 FFCore.deallocateAllScriptOwned(scriptType, uid);
2292 1178999 FFCore.reset_script_engine_data(scriptType, uid);
2293 1178999 expire_internal_script_arrays(scriptType, uid);
2294 1178999 }
2295
2296 // Same as "onDestroySprite", but for non-sprite things.
2297 1356646 void FFScript::destroyScriptableObject(ScriptType scriptType, const int32_t UID)
2298 {
2299 1356646 FFCore.deallocateAllScriptOwned(scriptType, UID);
2300 1356646 FFCore.reset_script_engine_data(scriptType, UID);
2301 1356646 expire_internal_script_arrays(scriptType, UID);
2302 1356646 }
2303
2304 37536 void FFScript::destroyScriptableObjectsOfType(ScriptType scriptType)
2305 {
2306 37536 FFCore.deallocateAllScriptOwnedOfType(scriptType);
2307 37536 FFCore.clear_script_engine_data_of_type(scriptType);
2308 37536 expire_internal_script_arrays(scriptType);
2309 37536 }
2310
2311 2738620 void FFScript::deallocateAllScriptOwned(ScriptType scriptType, const int32_t UID)
2312 {
2313 2738620 std::vector<uint32_t> ids_to_clear;
2314
8/14
✓ Branch 0 taken 2738620 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2738620 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2738620 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 73898788 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 71160168 times.
✓ Branch 9 taken 2738620 times.
✓ Branch 10 taken 71160168 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 71160168 times.
✗ Branch 13 not taken.
73898788 for (auto& script_object : script_objects | std::views::values)
2315 {
2316
3/4
✓ Branch 0 taken 71160168 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 149 times.
✓ Branch 3 taken 71160019 times.
71160168 if (script_object->script_own_clear(scriptType, UID))
2317 {
2318
1/2
✓ Branch 0 taken 149 times.
✗ Branch 1 not taken.
149 ids_to_clear.push_back(script_object->id);
2319
1/2
✓ Branch 0 taken 149 times.
✗ Branch 1 not taken.
149 script_object->disown();
2320 149 }
2321 }
2322
2323
6/8
✓ Branch 0 taken 2738620 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1244710 times.
✓ Branch 3 taken 1493910 times.
✓ Branch 4 taken 1244710 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 637885 times.
✓ Branch 7 taken 606825 times.
2738620 if (ZScriptVersion::gc() && script_engine_data_exists(scriptType, UID))
2324 {
2325
1/2
✓ Branch 0 taken 637885 times.
✗ Branch 1 not taken.
637885 auto& data = get_script_engine_data(scriptType, UID);
2326
2/2
✓ Branch 0 taken 619 times.
✓ Branch 1 taken 637885 times.
638504 for (uint32_t offset : data.ref.stack_pos_is_object)
2327 {
2328 619 uint32_t id = data.stack[offset];
2329
1/2
✓ Branch 0 taken 619 times.
✗ Branch 1 not taken.
619 ids_to_clear.push_back(id);
2330 }
2331 637885 data.ref.stack_pos_is_object.clear();
2332 637885 }
2333
2334
3/4
✓ Branch 0 taken 2738620 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1244710 times.
✓ Branch 3 taken 1493910 times.
2738620 if (ZScriptVersion::gc())
2335 {
2336
2/2
✓ Branch 0 taken 619 times.
✓ Branch 1 taken 1244710 times.
1245329 for (auto id : ids_to_clear)
2337
1/2
✓ Branch 0 taken 619 times.
✗ Branch 1 not taken.
619 script_object_ref_dec(id);
2338 1244710 }
2339 else
2340 {
2341
2/2
✓ Branch 0 taken 149 times.
✓ Branch 1 taken 1493910 times.
1494059 for (auto id : ids_to_clear)
2342
1/2
✓ Branch 0 taken 149 times.
✗ Branch 1 not taken.
149 delete_script_object(id);
2343 }
2344
2345
3/4
✓ Branch 0 taken 2738620 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1206784 times.
✓ Branch 3 taken 1531836 times.
2738620 if (!ZScriptVersion::gc_arrays())
2346 {
2347
2/2
✓ Branch 0 taken 6272868420 times.
✓ Branch 1 taken 1531836 times.
6274400256 for(int32_t i = 1; i < NUM_ZSCRIPT_ARRAYS; i++)
2348 {
2349
3/4
✓ Branch 0 taken 6272868420 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30496 times.
✓ Branch 3 taken 6272837924 times.
6272868420 if(arrayOwner[i].script_own_clear(scriptType,UID))
2350
1/2
✓ Branch 0 taken 30496 times.
✗ Branch 1 not taken.
30496 deallocateArray(i);
2351 6272868420 }
2352 1531836 }
2353 2738620 }
2354
2355 142236 void FFScript::deallocateAllScriptOwnedOfType(ScriptType scriptType)
2356 {
2357 142236 std::vector<uint32_t> ids_to_clear;
2358
8/14
✓ Branch 0 taken 142236 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 142236 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 142236 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 902661 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 760425 times.
✓ Branch 9 taken 142236 times.
✓ Branch 10 taken 760425 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 760425 times.
✗ Branch 13 not taken.
902661 for (auto& script_object : script_objects | std::views::values)
2359 {
2360
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 760425 times.
760425 if (script_object->owned_type == scriptType)
2361 {
2362 ids_to_clear.push_back(script_object->id);
2363 script_object->disown();
2364 }
2365 }
2366
2367
3/4
✓ Branch 0 taken 142236 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 73291 times.
✓ Branch 3 taken 68945 times.
142236 if (ZScriptVersion::gc())
2368 {
2369
2/2
✓ Branch 0 taken 196769577 times.
✓ Branch 1 taken 73291 times.
196849376 for (auto& [key, data] : scriptEngineDatas)
2370 {
2371
2/2
✓ Branch 0 taken 196763069 times.
✓ Branch 1 taken 6508 times.
196769577 if (key.first != scriptType)
2372 196763069 continue;
2373
2374
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6508 times.
6508 for (uint32_t offset : data.ref.stack_pos_is_object)
2375 {
2376 uint32_t id = data.stack[offset];
2377 ids_to_clear.push_back(id);
2378 }
2379 6508 data.ref.stack_pos_is_object.clear();
2380 }
2381
2382
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73291 times.
73291 for (auto id : ids_to_clear)
2383 script_object_ref_dec(id);
2384 73291 }
2385 else
2386 {
2387
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 68945 times.
68945 for (auto id : ids_to_clear)
2388 delete_script_object(id);
2389 }
2390
2391
3/4
✓ Branch 0 taken 142236 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 72890 times.
✓ Branch 3 taken 69346 times.
142236 if (!ZScriptVersion::gc_arrays())
2392 {
2393
2/2
✓ Branch 0 taken 283971870 times.
✓ Branch 1 taken 69346 times.
284041216 for(int32_t i = 1; i < NUM_ZSCRIPT_ARRAYS; i++)
2394 {
2395
1/2
✓ Branch 0 taken 283971870 times.
✗ Branch 1 not taken.
283971870 if(arrayOwner[i].owned_type == scriptType)
2396 deallocateArray(i);
2397 283971870 }
2398 69346 }
2399 142236 }
2400
2401 // Only called when resetting the engine. Don't keep anything.
2402 403 void FFScript::deallocateAllScriptOwned()
2403 {
2404 403 script_object_ids_by_type.clear();
2405 403 script_objects.clear();
2406 403 next_script_object_id_freelist.clear();
2407
2408
2/2
✓ Branch 0 taken 191 times.
✓ Branch 1 taken 212 times.
403 if (!ZScriptVersion::gc_arrays())
2409 {
2410
2/2
✓ Branch 0 taken 868140 times.
✓ Branch 1 taken 212 times.
868352 for(int32_t i = 1; i < NUM_ZSCRIPT_ARRAYS; i++)
2411 {
2412
2/2
✓ Branch 0 taken 867966 times.
✓ Branch 1 taken 174 times.
868140 if(localRAM[i].Valid())
2413 {
2414 // Unowned arrays are ALSO deallocated!
2415 174 arrayOwner[i].clear();
2416 174 localRAM[i].Clear();
2417 174 }
2418 868140 }
2419 212 }
2420 403 }
2421
2422 714 void FFScript::deallocateAllScriptOwnedCont()
2423 {
2424 714 std::vector<uint32_t> ids_to_clear;
2425
8/14
✓ Branch 0 taken 714 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 714 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 714 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5026 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4312 times.
✓ Branch 9 taken 714 times.
✓ Branch 10 taken 4312 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 4312 times.
✗ Branch 13 not taken.
5026 for (auto& script_object : script_objects | std::views::values)
2426 {
2427
2/4
✓ Branch 0 taken 4312 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4312 times.
4312 if (script_object->script_own_clear_cont())
2428 {
2429 ids_to_clear.push_back(script_object->id);
2430 script_object->disown();
2431 }
2432 }
2433
2434
3/4
✓ Branch 0 taken 714 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 323 times.
✓ Branch 3 taken 391 times.
714 if (ZScriptVersion::gc())
2435 {
2436
2/2
✓ Branch 0 taken 678285 times.
✓ Branch 1 taken 323 times.
1356894 for (auto& [key, data] : scriptEngineDatas)
2437 {
2438
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 678285 times.
678286 for (uint32_t offset : data.ref.stack_pos_is_object)
2439 {
2440 1 uint32_t id = data.stack[offset];
2441
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 ids_to_clear.push_back(id);
2442 }
2443 678285 data.ref.stack_pos_is_object.clear();
2444 }
2445
2446
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 323 times.
324 for (auto id : ids_to_clear)
2447
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 script_object_ref_dec(id);
2448 323 }
2449 else
2450 {
2451
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 391 times.
391 for (auto id : ids_to_clear)
2452 delete_script_object(id);
2453 }
2454
2455
3/4
✓ Branch 0 taken 714 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 323 times.
✓ Branch 3 taken 391 times.
714 if (!ZScriptVersion::gc_arrays())
2456 {
2457 //No QR check here- always deallocate on quest exit.
2458
2/2
✓ Branch 0 taken 1601145 times.
✓ Branch 1 taken 391 times.
1601536 for(int32_t i = 1; i < NUM_ZSCRIPT_ARRAYS; i++)
2459 {
2460
3/4
✓ Branch 0 taken 1601145 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3165 times.
✓ Branch 3 taken 1597980 times.
1601145 if(localRAM[i].Valid())
2461 {
2462
2/4
✓ Branch 0 taken 3165 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3165 times.
✗ Branch 3 not taken.
3165 if(arrayOwner[i].script_own_clear_cont())
2463
1/2
✓ Branch 0 taken 3165 times.
✗ Branch 1 not taken.
3165 deallocateArray(i);
2464 3165 }
2465 1601145 }
2466 391 }
2467 714 }
2468
2469 10585196 weapon *checkLWpn(int32_t uid)
2470 {
2471 10585196 return ResolveSprite<weapon>(uid, "lweapon");
2472 }
2473
2474 20622407 weapon *checkEWpn(int32_t uid)
2475 {
2476 20622407 return ResolveSprite<weapon>(uid, "eweapon");
2477 }
2478
2479 29700482 weapon *checkWpn(int32_t uid)
2480 {
2481 29700482 return ResolveSprite<weapon>(uid, "weapon");
2482 }
2483
2484 10426770 user_genscript *checkGenericScr(int32_t ref)
2485 {
2486
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10426770 times.
10426770 if (BC::checkBounds(ref, 1, NUMSCRIPTSGENERIC-1) != SH::_NoError)
2487 return NULL;
2488
2489 10426770 return &user_genscript::get(ref);
2490 10426770 }
2491 extern portal mirror_portal;
2492 portal *checkPortal(int32_t ref, bool skiperr = false)
2493 {
2494 if(ref == -1)
2495 return &mirror_portal;
2496
2497 portal* p = (portal*)portals.getByUID(ref);
2498 if(!p)
2499 {
2500 if(!skiperr)
2501 scripting_log_error_with_context("Invalid portal pointer: {}", ref);
2502 return nullptr;
2503 }
2504 return p;
2505 }
2506
2507 savedportal *checkSavedPortal(int32_t ref, bool skiperr = false)
2508 {
2509 savedportal* sp = game->getSavedPortal(ref);
2510 if(!sp)
2511 {
2512 if(!skiperr)
2513 scripting_log_error_with_context("Invalid savedportal pointer: {}", ref);
2514 return nullptr;
2515 }
2516 return sp;
2517 }
2518 int32_t getPortalFromSaved(savedportal* p)
2519 {
2520 if(p == &(game->saved_mirror_portal))
2521 return -1;
2522 portal* prtl = nullptr;
2523 portals.forEach([&](sprite& spr)
2524 {
2525 portal* tmp = (portal*)&spr;
2526 if(p->getUID() == tmp->saved_data)
2527 {
2528 prtl = tmp;
2529 return true;
2530 }
2531 return false;
2532 });
2533 return prtl ? prtl->getUID() : 0;
2534 }
2535
2536 static user_stack *checkStack(uint32_t id, bool skipError = false)
2537 {
2538 return user_stacks.check(id, skipError);
2539 }
2540
2541 521996 static user_rng *checkRNG(uint32_t id, bool skipError = false)
2542 {
2543 // A null RNG pointer is special-case, access engine rng.
2544
2/2
✓ Branch 0 taken 520473 times.
✓ Branch 1 taken 1523 times.
521996 if (id == 0) return &nulrng;
2545 1523 return user_rngs.check(id, skipError);
2546 521996 }
2547
2548 17949 user_paldata* checkPalData(int32_t ref, bool skipError)
2549 {
2550 17949 return user_paldatas.check(ref, skipError);
2551 }
2552
2553 129247 newcombo* checkCombo(int32_t ref, bool skipError)
2554 {
2555
2/4
✓ Branch 0 taken 129247 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 129247 times.
129247 if (ref < 0 || ref > (MAXCOMBOS-1) )
2556 {
2557 scripting_log_error_with_context("Invalid combodata ID: {}", ref);
2558 return nullptr;
2559 }
2560
2561 129247 return &combobuf[ref];
2562 129247 }
2563
2564 // TODO: replace with checkCombo.
2565 6241321 static bool checkComboRef()
2566 {
2567
2/4
✓ Branch 0 taken 6241321 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6241321 times.
6241321 if (GET_REF(combodataref) < 0 || GET_REF(combodataref) > (MAXCOMBOS-1))
2568 {
2569 scripting_log_error_with_context("Invalid combodata ID: {}", GET_REF(combodataref));
2570 return false;
2571 }
2572
2573 6241321 return true;
2574 6241321 }
2575
2576 newcombo* checkComboFromTriggerRef(dword ref)
2577 {
2578 ref = get_combo_from_trigger_ref(ref);
2579 return checkCombo(ref);
2580 }
2581
2582 381675 dmap* checkDmap(int32_t ref)
2583 {
2584
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 381675 times.
381675 if (BC::checkDMapID(ref) != SH::_NoError)
2585 return nullptr;
2586
2587 381675 return &DMaps[ref];
2588 381675 }
2589
2590 23489683 ffcdata* checkFFC(int32_t ref)
2591 {
2592 23489683 return ResolveFFC(ref);
2593 }
2594
2595 46968322 enemy* checkNPC(int32_t ref)
2596 {
2597 46968322 return ResolveNpc(ref);
2598 }
2599
2600 guydata* checkNPCData(int32_t ref)
2601 {
2602 if (ref >= 0 && ref < MAXNPCS)
2603 return &guysbuf[ref];
2604
2605 scripting_log_error_with_context("Invalid {} using UID = {}", "npcdata", ref);
2606 return nullptr;
2607 }
2608
2609 // TODO: replace with checkNPCData.
2610 6366 static bool checkNPCDataRef()
2611 {
2612
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6366 times.
6366 if( (unsigned) GET_REF(npcdataref) > (MAXNPCS-1) )
2613 {
2614 scripting_log_error_with_context("Invalid npcdata ID: {}", GET_REF(npcdataref));
2615 return false;
2616 }
2617
2618 6366 return true;
2619 6366 }
2620
2621 2240371 item* checkItem(int32_t ref)
2622 {
2623 2240371 return ResolveItemSprite(ref);
2624 }
2625
2626 167 itemdata* checkItemData(int32_t ref)
2627 {
2628
2/4
✓ Branch 0 taken 167 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 167 times.
✗ Branch 3 not taken.
167 if (ref >= 0 && ref < MAXITEMS)
2629 167 return &itemsbuf[ref];
2630
2631 scripting_log_error_with_context("Invalid {} using UID = {}", "itemdata", ref);
2632 return nullptr;
2633 167 }
2634
2635 131061686 mapdata* checkMapData(int32_t ref)
2636 {
2637 static mapdata last_result;
2638
2639 131061686 last_result = decode_mapdata_ref(ref);
2640
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 131061686 times.
131061686 if (!last_result.scr)
2641 {
2642 scripting_log_error_with_context("Invalid {} using UID = {}", "mapdata", ref);
2643 return nullptr;
2644 }
2645
2646 131061686 return &last_result;
2647 131061686 }
2648
2649 977428 mapscr* checkMapDataScr(int32_t ref)
2650 {
2651 977428 return decode_mapdata_ref(ref).scr;
2652 }
2653
2654 26486768 screendata* checkScreen(int32_t ref)
2655 {
2656 26486768 return (screendata*)get_scr_maybe(cur_map, ref);
2657 }
2658
2659 bottletype* checkBottleData(int32_t ref, bool skipError)
2660 {
2661 if(ref > 0 && ref <= 64)
2662 {
2663 return &QMisc.bottle_types[ref-1];
2664 }
2665 if(skipError) return NULL;
2666
2667 scripting_log_error_with_context("Invalid {} using UID = {}", "bottledata", ref);
2668 return NULL;
2669 }
2670
2671 bottleshoptype *checkBottleShopData(int32_t ref, bool skipError)
2672 {
2673 if(ref > 0 && ref <= 256)
2674 {
2675 return &QMisc.bottle_shop_types[ref-1];
2676 }
2677 if(skipError) return NULL;
2678
2679 scripting_log_error_with_context("Invalid {} using UID = {}", "bottleshopdata", ref);
2680 return NULL;
2681 }
2682
2683 item_drop_object *checkDropSetData(int32_t ref)
2684 {
2685 if(ref > 0 && ref < MAXITEMDROPSETS)
2686 return &item_drop_sets[ref];
2687
2688 scripting_log_error_with_context("Invalid {} using UID = {}", "dropsetdata", ref);
2689 return NULL;
2690 }
2691
2692 5603 wpndata *checkSpriteData(int32_t ref)
2693 {
2694
2/4
✓ Branch 0 taken 5603 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5603 times.
✗ Branch 3 not taken.
5603 if(ref > 0 && ref < MAXWPNS)
2695 5603 return &wpnsbuf[ref];
2696
2697 scripting_log_error_with_context("Invalid {} using UID = {}", "spritedata", ref);
2698 return NULL;
2699 5603 }
2700
2701 MsgStr *checkMessageData(int32_t ref)
2702 {
2703 if(ref > 0 && ref < msg_strings_size)
2704 return &MsgStrings[ref];
2705
2706 scripting_log_error_with_context("Invalid {} using UID = {}", "messagedata", ref);
2707 return NULL;
2708 }
2709
2710 combo_trigger* checkComboTrigger(dword ref)
2711 {
2712 return get_combo_trigger(ref);
2713 }
2714
2715 67027245 user_bitmap *checkBitmap(int32_t ref, bool req_valid = false, bool skipError = false)
2716 {
2717
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 67027245 times.
67027245 switch (ref - 10)
2718 {
2719 case rtSCREEN:
2720 case rtBMP0:
2721 case rtBMP1:
2722 case rtBMP2:
2723 case rtBMP3:
2724 case rtBMP4:
2725 case rtBMP5:
2726 case rtBMP6:
2727 zprint2("Internal error: 'checkBitmap()' recieved ref pointing to system bitmap!\n");
2728 zprint2("Please report this as a bug!\n");
2729
2730 if(skipError) return NULL;
2731
2732 scripting_log_error_with_context("Tried to reference a non-existent bitmap with UID = {}", ref);
2733 return NULL;
2734
2735 default:
2736 {
2737 67027245 user_bitmap* b = user_bitmaps.check(ref, skipError);
2738
4/6
✓ Branch 0 taken 66996830 times.
✓ Branch 1 taken 30415 times.
✓ Branch 2 taken 66996830 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 66996830 times.
✗ Branch 5 not taken.
67027245 if (req_valid && (!b || !b->u_bmp))
2739 {
2740 if (skipError) return NULL;
2741
2742 scripting_log_error_with_context("Tried to reference an invalid user bitmap with UID = {}.", ref);
2743 Z_scripterrlog("Did you forget to create the bitmap with `new bitmap()` or `->Create()`?.\n");
2744 return NULL;
2745 }
2746 67027245 return b;
2747 }
2748 }
2749 67027245 }
2750
2751 extern const std::string subscr_names[sstMAX];
2752 static std::string subscr_type_names(std::set<int> const& req_tys)
2753 {
2754 ostringstream oss;
2755 bool first = true;
2756 for (auto req_ty : req_tys)
2757 {
2758 if (first)
2759 first = false;
2760 else oss << ", ";
2761 oss << "'" << subscr_names[req_ty] << "'";
2762 }
2763 return oss.str();
2764 }
2765 159701 ZCSubscreen *checkSubData(int32_t ref, std::set<int> const& req_tys)
2766 {
2767 324499 auto [ptr,ty] = load_subdata(ref);
2768
1/2
✓ Branch 0 taken 159701 times.
✗ Branch 1 not taken.
159701 if(ptr)
2769 {
2770
3/4
✓ Branch 0 taken 154604 times.
✓ Branch 1 taken 5097 times.
✓ Branch 2 taken 159701 times.
✗ Branch 3 not taken.
159701 if(req_tys.empty() || req_tys.contains(ty))
2771 159701 return ptr;
2772 else
2773 {
2774 scripting_log_error_with_context("Wrong type of SubscreenData accessed! Expecting type [{}], but found '{}'",
2775 subscr_type_names(req_tys), subscr_names[ty]);
2776 }
2777 }
2778 else scripting_log_error_with_context("Script attempted to reference a nonexistent SubscreenData!");
2779
2780 scripting_log_error_with_context("You were trying to reference an invalid SubscreenData with UID = {}", ref);
2781 return NULL;
2782 159701 }
2783
2784 56028 SubscrPage *checkSubPage(int32_t ref, std::set<int> const& req_tys)
2785 {
2786 126926 auto [ptr,ty] = load_subpage(ref);
2787
1/2
✓ Branch 0 taken 56028 times.
✗ Branch 1 not taken.
56028 if(ptr)
2788 {
2789
3/4
✓ Branch 0 taken 41158 times.
✓ Branch 1 taken 14870 times.
✓ Branch 2 taken 56028 times.
✗ Branch 3 not taken.
56028 if(req_tys.empty() || req_tys.contains(ty))
2790 56028 return ptr;
2791 else
2792 {
2793 scripting_log_error_with_context("Wrong type of Subscreen accessed! Expecting type [{}], but found '{}'",
2794 subscr_type_names(req_tys), subscr_names[ty]);
2795 }
2796 }
2797 else scripting_log_error_with_context("Script attempted to reference a nonexistent SubscreenPage!");
2798
2799 scripting_log_error_with_context("You were trying to reference an invalid SubscreenPage with UID = {}", ref);
2800 return NULL;
2801 56028 }
2802
2803 103742 SubscrWidget *checkSubWidg(int32_t ref, std::set<int> const& req_sub_tys, int req_widg_ty)
2804 {
2805 207484 auto [ptr,ty] = load_subwidg(ref);
2806
1/2
✓ Branch 0 taken 103742 times.
✗ Branch 1 not taken.
103742 if(ptr)
2807 {
2808
2/4
✓ Branch 0 taken 103742 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103742 times.
✗ Branch 3 not taken.
103742 if(req_sub_tys.empty() || req_sub_tys.contains(ty))
2809 {
2810
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 103742 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
103742 if(req_widg_ty < 0 || req_widg_ty == ptr->getType())
2811 103742 return ptr;
2812 else
2813 {
2814 auto listdata = GUI::ZCListData::subscr_widgets();
2815 scripting_log_error_with_context("Wrong type of SubscreenWidget accessed! Expecting type '{}', but found '{}'",
2816 listdata.findText(req_widg_ty), listdata.findText(ptr->getType()));
2817 }
2818 }
2819 else
2820 {
2821 scripting_log_error_with_context("Wrong type of Subscreen accessed! Expecting subscreen type '{}', but found '{}'",
2822 subscr_type_names(req_sub_tys), subscr_names[ty]);
2823 }
2824 }
2825 else scripting_log_error_with_context("Script attempted to reference a nonexistent SubscreenWidget!");
2826
2827 scripting_log_error_with_context("You were trying to reference an invalid SubscreenWidget with UID = {}", ref);
2828 return NULL;
2829 103742 }
2830
2831 static void bad_subwidg_type(bool func, byte type)
2832 {
2833 auto tyname = type < widgMAX ? subwidg_internal_names[type].c_str() : "";
2834 scripting_log_error_with_context("Widget type {} '{}' does not have this {}!",
2835 type, tyname, func ? "function" : "value");
2836 }
2837
2838 3 int32_t item_flag(item_flags flag)
2839 {
2840
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
2841 {
2842 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
2843 return 0;
2844 }
2845 3 return (itemsbuf[GET_REF(itemdataref)].flags & flag) ? 10000 : 0;
2846 3 }
2847 void item_flag(item_flags flag, bool val)
2848 {
2849 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
2850 {
2851 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
2852 return;
2853 }
2854 SETFLAG(itemsbuf[GET_REF(itemdataref)].flags, flag, val);
2855 }
2856
2857 bool scripting_use_8bit_colors;
2858 int scripting_max_color_val;
2859
2860 440756 static int scripting_read_pal_color(int c)
2861 {
2862
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 440756 times.
440756 return scripting_use_8bit_colors ? c : c / 4;
2863 }
2864
2865 139440 static int scripting_write_pal_color(int c)
2866 {
2867
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 139440 times.
139440 return scripting_use_8bit_colors ? c : _rgb_scale_6[c];
2868 }
2869
2870 10440 void apply_qr_rule(int qr_id)
2871 {
2872 10440 bool value = get_qr(qr_id);
2873
8/8
✓ Branch 0 taken 1154 times.
✓ Branch 1 taken 1154 times.
✓ Branch 2 taken 2355 times.
✓ Branch 3 taken 1154 times.
✓ Branch 4 taken 1154 times.
✓ Branch 5 taken 1154 times.
✓ Branch 6 taken 1154 times.
✓ Branch 7 taken 1161 times.
10440 switch (qr_id)
2874 {
2875 case qr_LTTPWALK:
2876 1154 Hero.setDiagMove(value?1:0);
2877 1154 break;
2878 case qr_LTTPCOLLISION:
2879 1154 Hero.setBigHitbox(value?1:0);
2880 1154 break;
2881 case qr_ZS_NO_NEG_ARRAY:
2882 1154 can_neg_array = !value;
2883 1154 break;
2884 case qr_SCRIPTS_6_BIT_COLOR:
2885 {
2886
2/2
✓ Branch 0 taken 1152 times.
✓ Branch 1 taken 2 times.
1154 if (value)
2887 {
2888 1152 scripting_use_8bit_colors = false;
2889 1152 scripting_max_color_val = 63;
2890 1152 }
2891 else
2892 {
2893 2 scripting_use_8bit_colors = true;
2894 2 scripting_max_color_val = 255;
2895 }
2896 1154 break;
2897 }
2898 case qr_HIDE_BOTTOM_8_PIXELS:
2899 {
2900 1161 updateShowBottomPixels();
2901 1161 break;
2902 }
2903 case qr_COOLSCROLL:
2904 case qr_FADEBLACKWIPE:
2905 case qr_OVALWIPE:
2906 case qr_SMASWIPE:
2907 case qr_TRIANGLEWIPE:
2908 {
2909 1154 COOLSCROLL =
2910 3462 (get_qr(qr_COOLSCROLL)!=0 ? 1 : 0) |
2911 2308 (get_qr(qr_OVALWIPE)!=0 ? 2 : 0) |
2912 2308 (get_qr(qr_TRIANGLEWIPE)!=0 ? 4 : 0) |
2913 2308 (get_qr(qr_SMASWIPE)!=0 ? 8 : 0) |
2914 1154 (get_qr(qr_FADEBLACKWIPE)!=0 ? 16 : 0);
2915 1154 break;
2916 }
2917 case qr_BSZELDA:
2918 {
2919 1154 BSZ = value;
2920 1154 break;
2921 }
2922 }
2923 10440 }
2924
2925 1154 static void apply_qr_rules()
2926 {
2927 1154 apply_qr_rule(qr_BSZELDA);
2928 1154 apply_qr_rule(qr_COOLSCROLL);
2929 1154 apply_qr_rule(qr_HIDE_BOTTOM_8_PIXELS);
2930 1154 apply_qr_rule(qr_LTTPCOLLISION);
2931 1154 apply_qr_rule(qr_LTTPWALK);
2932 1154 apply_qr_rule(qr_SCRIPTS_6_BIT_COLOR);
2933 1154 apply_qr_rule(qr_ZS_NO_NEG_ARRAY);
2934 1154 }
2935
2936 //Forward decl
2937 int32_t do_msgheight(int32_t msg);
2938 int32_t do_msgwidth(int32_t msg);
2939 //
2940
2941 template <typename T, size_t N>
2942 static int read_array(const T(&arr)[N], int index)
2943 {
2944 if (BC::checkIndex(index, 0, N - 1) != SH::_NoError)
2945 return 0;
2946
2947 return arr[index];
2948 }
2949
2950 template <typename T, size_t N>
2951 static bool write_array(T(&arr)[N], int index, T value)
2952 {
2953 if (BC::checkIndex(index, 0, N - 1) != SH::_NoError)
2954 return false;
2955
2956 arr[index] = value;
2957 return true;
2958 }
2959
2960 284185426 static int get_ref(int arg)
2961 {
2962
15/36
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 129247 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 380040 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 27478207 times.
✓ Branch 12 taken 23489683 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 10419009 times.
✓ Branch 15 taken 169801 times.
✓ Branch 16 taken 167 times.
✓ Branch 17 taken 2222271 times.
✓ Branch 18 taken 131480945 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 46964387 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✓ Branch 26 taken 29098152 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 12300960 times.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✓ Branch 31 taken 49980 times.
✓ Branch 32 taken 2475 times.
✓ Branch 33 taken 102 times.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
284185426 switch (arg)
2963 {
2964 case CLASS_THISKEY: return ri->thiskey;
2965 case CLASS_THISKEY2: return ri->thiskey2;
2966 case REFBITMAP: return ri->bitmapref;
2967 case REFBOTTLESHOP: return ri->bottleshopref;
2968 case REFBOTTLETYPE: return ri->bottletyperef;
2969 129247 case REFCOMBODATA: return ri->combodataref;
2970 case REFCOMBOTRIGGER: return ri->combotriggerref;
2971 case REFDIRECTORY: return ri->directoryref;
2972 380040 case REFDMAPDATA: return ri->dmapdataref;
2973 case REFDROPSETDATA: return ri->dropsetdataref;
2974 27478207 case REFEWPN: return ri->ewpnref;
2975 23489683 case REFFFC: return ri->ffcref;
2976 case REFFILE: return ri->fileref;
2977 10419009 case REFGENERICDATA: return ri->genericdataref;
2978 169801 case REFITEM: return ri->itemref;
2979 167 case REFITEMDATA: return ri->itemdataref;
2980 2222271 case REFLWPN: return ri->lwpnref;
2981 131480945 case REFMAPDATA: return ri->mapdataref;
2982 case REFMSGDATA: return ri->msgdataref;
2983 46964387 case REFNPC: return ri->npcref;
2984 case REFNPCDATA: return ri->npcdataref;
2985 case REFPALDATA: return ri->paldataref;
2986 case REFPORTAL: return ri->portalref;
2987 case REFRNG: return ri->rngref;
2988 case REFSAVPORTAL: return ri->savportalref;
2989 29098152 case REFSCREEN: return ri->screenref;
2990 case REFSHOPDATA: return ri->shopdataref;
2991 12300960 case REFSPRITE: return ri->spriteref;
2992 case REFSPRITEDATA: return ri->spritedataref;
2993 case REFSTACK: return ri->stackref;
2994 49980 case REFSUBSCREENDATA: return ri->subscreendataref;
2995 2475 case REFSUBSCREENPAGE: return ri->subscreenpageref;
2996 102 case REFSUBSCREENWIDG: return ri->subscreenwidgref;
2997 case REFWEBSOCKET: return ri->websocketref;
2998 case REFSAVEMENU: return ri->savemenuref;
2999
3000 default: NOTREACHED();
3001 }
3002 284185426 }
3003
3004 int32_t earlyretval = -1;
3005 4569413646 int32_t get_register(int32_t arg)
3006 {
3007
3/4
✓ Branch 0 taken 4569413646 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3270460183 times.
✓ Branch 3 taken 1298953463 times.
4569413646 if (arg >= D(0) && arg <= D(7))
3008 1298953463 return ri->d[arg - D(0)];
3009
3010
4/4
✓ Branch 0 taken 2675213551 times.
✓ Branch 1 taken 595246632 times.
✓ Branch 2 taken 2646579976 times.
✓ Branch 3 taken 28633575 times.
3270460183 if (arg >= GD(0) && arg <= GD(MAX_SCRIPT_REGISTERS))
3011 28633575 return game->global_d[arg - GD(0)];
3012
3013 3241826608 int32_t ret = 0;
3014
3015 #define GET_SPRITEDATA_VAR_INT(member) \
3016 { \
3017 if(unsigned(GET_REF(spritedataref)) > (MAXWPNS-1) ) \
3018 { \
3019 ret = -10000; \
3020 scripting_log_error_with_context("Invalid Sprite ID: {}", GET_REF(spritedataref)*10000); \
3021 } \
3022 else \
3023 ret = (wpnsbuf[GET_REF(spritedataref)].member * 10000); \
3024 }
3025
3026 3241826608 current_zasm_register = arg;
3027
3028 // Do not ever use `return` in these cases!
3029
289/1063
✗ Branch 0 not taken.
✓ Branch 1 taken 1125668249 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 765028632 times.
✓ Branch 4 taken 3175268 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 623633 times.
✓ Branch 7 taken 13073815 times.
✓ Branch 8 taken 531425047 times.
✓ Branch 9 taken 2312686 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 24185371 times.
✓ Branch 12 taken 23746252 times.
✓ Branch 13 taken 5823966 times.
✓ Branch 14 taken 163102 times.
✓ Branch 15 taken 377 times.
✓ Branch 16 taken 51 times.
✓ Branch 17 taken 51 times.
✓ Branch 18 taken 204076 times.
✓ Branch 19 taken 199035 times.
✓ Branch 20 taken 5283857 times.
✓ Branch 21 taken 5194596 times.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✓ Branch 24 taken 44546640 times.
✗ Branch 25 not taken.
✓ Branch 26 taken 46258150 times.
✓ Branch 27 taken 4050508 times.
✓ Branch 28 taken 722055 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 9096958 times.
✓ Branch 31 taken 441276 times.
✓ Branch 32 taken 27115597 times.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✓ Branch 35 taken 3407280 times.
✓ Branch 36 taken 1063999 times.
✓ Branch 37 taken 944878 times.
✓ Branch 38 taken 97951537 times.
✗ Branch 39 not taken.
✓ Branch 40 taken 204 times.
✓ Branch 41 taken 12148 times.
✗ Branch 42 not taken.
✓ Branch 43 taken 1249005 times.
✓ Branch 44 taken 837632 times.
✓ Branch 45 taken 654959 times.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✓ Branch 49 taken 2161763 times.
✓ Branch 50 taken 1095514 times.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✓ Branch 54 taken 656387 times.
✓ Branch 55 taken 571655 times.
✓ Branch 56 taken 113145 times.
✓ Branch 57 taken 115547 times.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✓ Branch 62 taken 489104 times.
✓ Branch 63 taken 489104 times.
✓ Branch 64 taken 288295 times.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✓ Branch 67 taken 4101 times.
✗ Branch 68 not taken.
✓ Branch 69 taken 57322 times.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✓ Branch 75 taken 180367 times.
✓ Branch 76 taken 440896 times.
✓ Branch 77 taken 2 times.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
✓ Branch 80 taken 429515 times.
✓ Branch 81 taken 433515 times.
✓ Branch 82 taken 337540 times.
✓ Branch 83 taken 274017 times.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✓ Branch 86 taken 271788 times.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 90 not taken.
✓ Branch 91 taken 834841 times.
✓ Branch 92 taken 18 times.
✗ Branch 93 not taken.
✗ Branch 94 not taken.
✓ Branch 95 taken 4357 times.
✗ Branch 96 not taken.
✓ Branch 97 taken 13171261 times.
✗ Branch 98 not taken.
✗ Branch 99 not taken.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✗ Branch 102 not taken.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 105 not taken.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✗ Branch 108 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
✗ Branch 111 not taken.
✗ Branch 112 not taken.
✗ Branch 113 not taken.
✗ Branch 114 not taken.
✓ Branch 115 taken 136185 times.
✗ Branch 116 not taken.
✗ Branch 117 not taken.
✗ Branch 118 not taken.
✗ Branch 119 not taken.
✗ Branch 120 not taken.
✗ Branch 121 not taken.
✗ Branch 122 not taken.
✗ Branch 123 not taken.
✓ Branch 124 taken 98023 times.
✓ Branch 125 taken 4123 times.
✓ Branch 126 taken 5056867 times.
✓ Branch 127 taken 4410418 times.
✓ Branch 128 taken 4977391 times.
✓ Branch 129 taken 5016239 times.
✓ Branch 130 taken 11970574 times.
✓ Branch 131 taken 10596134 times.
✓ Branch 132 taken 6428754 times.
✓ Branch 133 taken 6424495 times.
✓ Branch 134 taken 122646 times.
✓ Branch 135 taken 122937 times.
✓ Branch 136 taken 23391 times.
✓ Branch 137 taken 23391 times.
✗ Branch 138 not taken.
✗ Branch 139 not taken.
✗ Branch 140 not taken.
✗ Branch 141 not taken.
✓ Branch 142 taken 1054708 times.
✓ Branch 143 taken 1318385 times.
✗ Branch 144 not taken.
✓ Branch 145 taken 1073638 times.
✓ Branch 146 taken 1102950 times.
✓ Branch 147 taken 335996 times.
✓ Branch 148 taken 2151876 times.
✓ Branch 149 taken 1578611 times.
✓ Branch 150 taken 1805665 times.
✓ Branch 151 taken 1291881 times.
✓ Branch 152 taken 4122120 times.
✓ Branch 153 taken 3447036 times.
✓ Branch 154 taken 3697426 times.
✓ Branch 155 taken 3481646 times.
✓ Branch 156 taken 1779092 times.
✓ Branch 157 taken 1349984 times.
✓ Branch 158 taken 833679 times.
✓ Branch 159 taken 669416 times.
✗ Branch 160 not taken.
✗ Branch 161 not taken.
✗ Branch 162 not taken.
✗ Branch 163 not taken.
✗ Branch 164 not taken.
✗ Branch 165 not taken.
✗ Branch 166 not taken.
✗ Branch 167 not taken.
✗ Branch 168 not taken.
✗ Branch 169 not taken.
✗ Branch 170 not taken.
✗ Branch 171 not taken.
✗ Branch 172 not taken.
✗ Branch 173 not taken.
✗ Branch 174 not taken.
✗ Branch 175 not taken.
✗ Branch 176 not taken.
✗ Branch 177 not taken.
✗ Branch 178 not taken.
✗ Branch 179 not taken.
✗ Branch 180 not taken.
✗ Branch 181 not taken.
✗ Branch 182 not taken.
✗ Branch 183 not taken.
✗ Branch 184 not taken.
✗ Branch 185 not taken.
✗ Branch 186 not taken.
✗ Branch 187 not taken.
✗ Branch 188 not taken.
✗ Branch 189 not taken.
✓ Branch 190 taken 53 times.
✗ Branch 191 not taken.
✗ Branch 192 not taken.
✗ Branch 193 not taken.
✗ Branch 194 not taken.
✗ Branch 195 not taken.
✓ Branch 196 taken 58309993 times.
✓ Branch 197 taken 668845 times.
✓ Branch 198 taken 3 times.
✗ Branch 199 not taken.
✗ Branch 200 not taken.
✗ Branch 201 not taken.
✗ Branch 202 not taken.
✗ Branch 203 not taken.
✗ Branch 204 not taken.
✗ Branch 205 not taken.
✗ Branch 206 not taken.
✗ Branch 207 not taken.
✗ Branch 208 not taken.
✗ Branch 209 not taken.
✗ Branch 210 not taken.
✗ Branch 211 not taken.
✗ Branch 212 not taken.
✓ Branch 213 taken 1994 times.
✓ Branch 214 taken 1918 times.
✗ Branch 215 not taken.
✗ Branch 216 not taken.
✗ Branch 217 not taken.
✗ Branch 218 not taken.
✗ Branch 219 not taken.
✗ Branch 220 not taken.
✗ Branch 221 not taken.
✗ Branch 222 not taken.
✗ Branch 223 not taken.
✗ Branch 224 not taken.
✗ Branch 225 not taken.
✗ Branch 226 not taken.
✗ Branch 227 not taken.
✗ Branch 228 not taken.
✓ Branch 229 taken 55709 times.
✗ Branch 230 not taken.
✓ Branch 231 taken 55684 times.
✗ Branch 232 not taken.
✓ Branch 233 taken 63041 times.
✓ Branch 234 taken 142873 times.
✓ Branch 235 taken 74538 times.
✗ Branch 236 not taken.
✗ Branch 237 not taken.
✗ Branch 238 not taken.
✗ Branch 239 not taken.
✗ Branch 240 not taken.
✗ Branch 241 not taken.
✗ Branch 242 not taken.
✗ Branch 243 not taken.
✗ Branch 244 not taken.
✗ Branch 245 not taken.
✗ Branch 246 not taken.
✓ Branch 247 taken 954757 times.
✗ Branch 248 not taken.
✓ Branch 249 taken 950150 times.
✓ Branch 250 taken 109736 times.
✓ Branch 251 taken 6 times.
✗ Branch 252 not taken.
✓ Branch 253 taken 80933 times.
✗ Branch 254 not taken.
✓ Branch 255 taken 5388 times.
✓ Branch 256 taken 416 times.
✗ Branch 257 not taken.
✓ Branch 258 taken 246 times.
✗ Branch 259 not taken.
✓ Branch 260 taken 6 times.
✗ Branch 261 not taken.
✗ Branch 262 not taken.
✓ Branch 263 taken 6 times.
✓ Branch 264 taken 104531 times.
✓ Branch 265 taken 8339 times.
✓ Branch 266 taken 4517186 times.
✓ Branch 267 taken 53697 times.
✓ Branch 268 taken 586 times.
✗ Branch 269 not taken.
✓ Branch 270 taken 53381 times.
✓ Branch 271 taken 220 times.
✓ Branch 272 taken 4362 times.
✓ Branch 273 taken 6 times.
✓ Branch 274 taken 4622 times.
✓ Branch 275 taken 6 times.
✗ Branch 276 not taken.
✓ Branch 277 taken 2001860 times.
✓ Branch 278 taken 6 times.
✓ Branch 279 taken 835937 times.
✓ Branch 280 taken 23909 times.
✓ Branch 281 taken 299718 times.
✓ Branch 282 taken 296970 times.
✓ Branch 283 taken 10231 times.
✓ Branch 284 taken 11477 times.
✗ Branch 285 not taken.
✗ Branch 286 not taken.
✗ Branch 287 not taken.
✓ Branch 288 taken 6 times.
✓ Branch 289 taken 283042 times.
✓ Branch 290 taken 284996 times.
✓ Branch 291 taken 36540 times.
✓ Branch 292 taken 32019 times.
✓ Branch 293 taken 32019 times.
✓ Branch 294 taken 5469 times.
✗ Branch 295 not taken.
✓ Branch 296 taken 2166 times.
✗ Branch 297 not taken.
✓ Branch 298 taken 3 times.
✓ Branch 299 taken 60075 times.
✗ Branch 300 not taken.
✗ Branch 301 not taken.
✗ Branch 302 not taken.
✓ Branch 303 taken 1552 times.
✗ Branch 304 not taken.
✗ Branch 305 not taken.
✗ Branch 306 not taken.
✗ Branch 307 not taken.
✓ Branch 308 taken 48553 times.
✗ Branch 309 not taken.
✗ Branch 310 not taken.
✗ Branch 311 not taken.
✗ Branch 312 not taken.
✗ Branch 313 not taken.
✗ Branch 314 not taken.
✗ Branch 315 not taken.
✗ Branch 316 not taken.
✗ Branch 317 not taken.
✗ Branch 318 not taken.
✗ Branch 319 not taken.
✗ Branch 320 not taken.
✗ Branch 321 not taken.
✗ Branch 322 not taken.
✓ Branch 323 taken 4354592 times.
✗ Branch 324 not taken.
✓ Branch 325 taken 4354690 times.
✓ Branch 326 taken 552907 times.
✗ Branch 327 not taken.
✗ Branch 328 not taken.
✓ Branch 329 taken 61563 times.
✓ Branch 330 taken 2845 times.
✗ Branch 331 not taken.
✓ Branch 332 taken 647006 times.
✓ Branch 333 taken 908111 times.
✓ Branch 334 taken 3341 times.
✗ Branch 335 not taken.
✗ Branch 336 not taken.
✓ Branch 337 taken 170980 times.
✗ Branch 338 not taken.
✗ Branch 339 not taken.
✓ Branch 340 taken 46359 times.
✓ Branch 341 taken 99454 times.
✓ Branch 342 taken 6052 times.
✓ Branch 343 taken 2973313 times.
✓ Branch 344 taken 205116 times.
✗ Branch 345 not taken.
✗ Branch 346 not taken.
✓ Branch 347 taken 65418 times.
✗ Branch 348 not taken.
✓ Branch 349 taken 32642 times.
✗ Branch 350 not taken.
✓ Branch 351 taken 32642 times.
✗ Branch 352 not taken.
✓ Branch 353 taken 12006 times.
✓ Branch 354 taken 218 times.
✓ Branch 355 taken 6662300 times.
✗ Branch 356 not taken.
✓ Branch 357 taken 10635 times.
✗ Branch 358 not taken.
✓ Branch 359 taken 157773 times.
✓ Branch 360 taken 157773 times.
✓ Branch 361 taken 48464 times.
✓ Branch 362 taken 60558 times.
✗ Branch 363 not taken.
✗ Branch 364 not taken.
✗ Branch 365 not taken.
✓ Branch 366 taken 1880 times.
✓ Branch 367 taken 149564 times.
✓ Branch 368 taken 149564 times.
✓ Branch 369 taken 81355 times.
✓ Branch 370 taken 125257 times.
✓ Branch 371 taken 125257 times.
✓ Branch 372 taken 13583 times.
✗ Branch 373 not taken.
✗ Branch 374 not taken.
✗ Branch 375 not taken.
✗ Branch 376 not taken.
✓ Branch 377 taken 7570 times.
✗ Branch 378 not taken.
✗ Branch 379 not taken.
✗ Branch 380 not taken.
✗ Branch 381 not taken.
✗ Branch 382 not taken.
✓ Branch 383 taken 30735 times.
✗ Branch 384 not taken.
✗ Branch 385 not taken.
✗ Branch 386 not taken.
✗ Branch 387 not taken.
✗ Branch 388 not taken.
✗ Branch 389 not taken.
✗ Branch 390 not taken.
✗ Branch 391 not taken.
✗ Branch 392 not taken.
✗ Branch 393 not taken.
✗ Branch 394 not taken.
✗ Branch 395 not taken.
✗ Branch 396 not taken.
✗ Branch 397 not taken.
✓ Branch 398 taken 823233 times.
✗ Branch 399 not taken.
✗ Branch 400 not taken.
✗ Branch 401 not taken.
✓ Branch 402 taken 450 times.
✓ Branch 403 taken 107342 times.
✓ Branch 404 taken 12771624 times.
✓ Branch 405 taken 96 times.
✗ Branch 406 not taken.
✓ Branch 407 taken 65088706 times.
✓ Branch 408 taken 16014487 times.
✗ Branch 409 not taken.
✗ Branch 410 not taken.
✗ Branch 411 not taken.
✓ Branch 412 taken 390647 times.
✓ Branch 413 taken 382914 times.
✓ Branch 414 taken 2662 times.
✓ Branch 415 taken 2599 times.
✓ Branch 416 taken 11700413 times.
✓ Branch 417 taken 27276802 times.
✗ Branch 418 not taken.
✗ Branch 419 not taken.
✗ Branch 420 not taken.
✓ Branch 421 taken 24940 times.
✓ Branch 422 taken 21112 times.
✓ Branch 423 taken 8014 times.
✓ Branch 424 taken 11842 times.
✗ Branch 425 not taken.
✗ Branch 426 not taken.
✗ Branch 427 not taken.
✗ Branch 428 not taken.
✗ Branch 429 not taken.
✗ Branch 430 not taken.
✗ Branch 431 not taken.
✗ Branch 432 not taken.
✗ Branch 433 not taken.
✗ Branch 434 not taken.
✗ Branch 435 not taken.
✗ Branch 436 not taken.
✓ Branch 437 taken 170974 times.
✗ Branch 438 not taken.
✗ Branch 439 not taken.
✗ Branch 440 not taken.
✗ Branch 441 not taken.
✗ Branch 442 not taken.
✗ Branch 443 not taken.
✗ Branch 444 not taken.
✗ Branch 445 not taken.
✗ Branch 446 not taken.
✗ Branch 447 not taken.
✗ Branch 448 not taken.
✗ Branch 449 not taken.
✗ Branch 450 not taken.
✗ Branch 451 not taken.
✗ Branch 452 not taken.
✗ Branch 453 not taken.
✗ Branch 454 not taken.
✗ Branch 455 not taken.
✗ Branch 456 not taken.
✗ Branch 457 not taken.
✗ Branch 458 not taken.
✗ Branch 459 not taken.
✗ Branch 460 not taken.
✗ Branch 461 not taken.
✗ Branch 462 not taken.
✗ Branch 463 not taken.
✗ Branch 464 not taken.
✓ Branch 465 taken 17 times.
✗ Branch 466 not taken.
✗ Branch 467 not taken.
✗ Branch 468 not taken.
✗ Branch 469 not taken.
✗ Branch 470 not taken.
✓ Branch 471 taken 41995 times.
✗ Branch 472 not taken.
✗ Branch 473 not taken.
✓ Branch 474 taken 13968 times.
✓ Branch 475 taken 43250 times.
✗ Branch 476 not taken.
✓ Branch 477 taken 280 times.
✗ Branch 478 not taken.
✗ Branch 479 not taken.
✗ Branch 480 not taken.
✗ Branch 481 not taken.
✗ Branch 482 not taken.
✓ Branch 483 taken 10246 times.
✓ Branch 484 taken 7214 times.
✓ Branch 485 taken 2391 times.
✓ Branch 486 taken 29999777 times.
✓ Branch 487 taken 47 times.
✓ Branch 488 taken 2 times.
✓ Branch 489 taken 748773 times.
✓ Branch 490 taken 112484 times.
✗ Branch 491 not taken.
✗ Branch 492 not taken.
✗ Branch 493 not taken.
✓ Branch 494 taken 1634 times.
✓ Branch 495 taken 1608 times.
✓ Branch 496 taken 32 times.
✗ Branch 497 not taken.
✗ Branch 498 not taken.
✗ Branch 499 not taken.
✓ Branch 500 taken 5603 times.
✗ Branch 501 not taken.
✓ Branch 502 taken 5603 times.
✗ Branch 503 not taken.
✓ Branch 504 taken 5603 times.
✓ Branch 505 taken 5603 times.
✗ Branch 506 not taken.
✗ Branch 507 not taken.
✓ Branch 508 taken 7237302 times.
✓ Branch 509 taken 1509497 times.
✓ Branch 510 taken 51072 times.
✗ Branch 511 not taken.
✗ Branch 512 not taken.
✗ Branch 513 not taken.
✗ Branch 514 not taken.
✗ Branch 515 not taken.
✗ Branch 516 not taken.
✗ Branch 517 not taken.
✗ Branch 518 not taken.
✗ Branch 519 not taken.
✗ Branch 520 not taken.
✗ Branch 521 not taken.
✗ Branch 522 not taken.
✓ Branch 523 taken 51072 times.
✗ Branch 524 not taken.
✗ Branch 525 not taken.
✗ Branch 526 not taken.
✗ Branch 527 not taken.
✗ Branch 528 not taken.
✗ Branch 529 not taken.
✗ Branch 530 not taken.
✗ Branch 531 not taken.
✗ Branch 532 not taken.
✗ Branch 533 not taken.
✗ Branch 534 not taken.
✗ Branch 535 not taken.
✗ Branch 536 not taken.
✗ Branch 537 not taken.
✗ Branch 538 not taken.
✗ Branch 539 not taken.
✗ Branch 540 not taken.
✗ Branch 541 not taken.
✗ Branch 542 not taken.
✗ Branch 543 not taken.
✗ Branch 544 not taken.
✗ Branch 545 not taken.
✓ Branch 546 taken 32 times.
✓ Branch 547 taken 2004 times.
✗ Branch 548 not taken.
✗ Branch 549 not taken.
✗ Branch 550 not taken.
✗ Branch 551 not taken.
✗ Branch 552 not taken.
✗ Branch 553 not taken.
✗ Branch 554 not taken.
✗ Branch 555 not taken.
✗ Branch 556 not taken.
✗ Branch 557 not taken.
✗ Branch 558 not taken.
✓ Branch 559 taken 151527 times.
✓ Branch 560 taken 314379 times.
✗ Branch 561 not taken.
✗ Branch 562 not taken.
✗ Branch 563 not taken.
✗ Branch 564 not taken.
✓ Branch 565 taken 1402 times.
✓ Branch 566 taken 193590 times.
✗ Branch 567 not taken.
✗ Branch 568 not taken.
✓ Branch 569 taken 8824 times.
✓ Branch 570 taken 128960 times.
✓ Branch 571 taken 51092 times.
✓ Branch 572 taken 814 times.
✗ Branch 573 not taken.
✗ Branch 574 not taken.
✗ Branch 575 not taken.
✗ Branch 576 not taken.
✓ Branch 577 taken 13125 times.
✓ Branch 578 taken 1192906 times.
✗ Branch 579 not taken.
✗ Branch 580 not taken.
✓ Branch 581 taken 5120 times.
✗ Branch 582 not taken.
✗ Branch 583 not taken.
✗ Branch 584 not taken.
✗ Branch 585 not taken.
✗ Branch 586 not taken.
✗ Branch 587 not taken.
✗ Branch 588 not taken.
✗ Branch 589 not taken.
✗ Branch 590 not taken.
✓ Branch 591 taken 23552 times.
✗ Branch 592 not taken.
✗ Branch 593 not taken.
✗ Branch 594 not taken.
✗ Branch 595 not taken.
✗ Branch 596 not taken.
✗ Branch 597 not taken.
✗ Branch 598 not taken.
✗ Branch 599 not taken.
✗ Branch 600 not taken.
✗ Branch 601 not taken.
✗ Branch 602 not taken.
✗ Branch 603 not taken.
✗ Branch 604 not taken.
✗ Branch 605 not taken.
✗ Branch 606 not taken.
✗ Branch 607 not taken.
✗ Branch 608 not taken.
✗ Branch 609 not taken.
✗ Branch 610 not taken.
✗ Branch 611 not taken.
✗ Branch 612 not taken.
✗ Branch 613 not taken.
✗ Branch 614 not taken.
✗ Branch 615 not taken.
✗ Branch 616 not taken.
✓ Branch 617 taken 182307 times.
✓ Branch 618 taken 134178 times.
✓ Branch 619 taken 629336 times.
✓ Branch 620 taken 19185 times.
✓ Branch 621 taken 116988 times.
✓ Branch 622 taken 122133 times.
✓ Branch 623 taken 9711 times.
✗ Branch 624 not taken.
✓ Branch 625 taken 2 times.
✓ Branch 626 taken 14257 times.
✓ Branch 627 taken 6890 times.
✓ Branch 628 taken 755 times.
✓ Branch 629 taken 12398 times.
✗ Branch 630 not taken.
✗ Branch 631 not taken.
✓ Branch 632 taken 528885 times.
✓ Branch 633 taken 2 times.
✗ Branch 634 not taken.
✗ Branch 635 not taken.
✗ Branch 636 not taken.
✗ Branch 637 not taken.
✗ Branch 638 not taken.
✗ Branch 639 not taken.
✓ Branch 640 taken 5429248 times.
✓ Branch 641 taken 18 times.
✗ Branch 642 not taken.
✗ Branch 643 not taken.
✗ Branch 644 not taken.
✗ Branch 645 not taken.
✗ Branch 646 not taken.
✗ Branch 647 not taken.
✗ Branch 648 not taken.
✗ Branch 649 not taken.
✗ Branch 650 not taken.
✗ Branch 651 not taken.
✗ Branch 652 not taken.
✗ Branch 653 not taken.
✗ Branch 654 not taken.
✗ Branch 655 not taken.
✗ Branch 656 not taken.
✓ Branch 657 taken 25 times.
✗ Branch 658 not taken.
✗ Branch 659 not taken.
✗ Branch 660 not taken.
✗ Branch 661 not taken.
✗ Branch 662 not taken.
✗ Branch 663 not taken.
✗ Branch 664 not taken.
✗ Branch 665 not taken.
✗ Branch 666 not taken.
✗ Branch 667 not taken.
✗ Branch 668 not taken.
✗ Branch 669 not taken.
✗ Branch 670 not taken.
✗ Branch 671 not taken.
✗ Branch 672 not taken.
✗ Branch 673 not taken.
✗ Branch 674 not taken.
✗ Branch 675 not taken.
✗ Branch 676 not taken.
✗ Branch 677 not taken.
✗ Branch 678 not taken.
✗ Branch 679 not taken.
✗ Branch 680 not taken.
✗ Branch 681 not taken.
✗ Branch 682 not taken.
✗ Branch 683 not taken.
✗ Branch 684 not taken.
✗ Branch 685 not taken.
✗ Branch 686 not taken.
✗ Branch 687 not taken.
✗ Branch 688 not taken.
✗ Branch 689 not taken.
✗ Branch 690 not taken.
✗ Branch 691 not taken.
✗ Branch 692 not taken.
✗ Branch 693 not taken.
✗ Branch 694 not taken.
✗ Branch 695 not taken.
✗ Branch 696 not taken.
✗ Branch 697 not taken.
✓ Branch 698 taken 5246834 times.
✗ Branch 699 not taken.
✗ Branch 700 not taken.
✗ Branch 701 not taken.
✗ Branch 702 not taken.
✗ Branch 703 not taken.
✗ Branch 704 not taken.
✗ Branch 705 not taken.
✗ Branch 706 not taken.
✗ Branch 707 not taken.
✗ Branch 708 not taken.
✗ Branch 709 not taken.
✗ Branch 710 not taken.
✗ Branch 711 not taken.
✗ Branch 712 not taken.
✗ Branch 713 not taken.
✗ Branch 714 not taken.
✗ Branch 715 not taken.
✗ Branch 716 not taken.
✗ Branch 717 not taken.
✗ Branch 718 not taken.
✗ Branch 719 not taken.
✗ Branch 720 not taken.
✗ Branch 721 not taken.
✗ Branch 722 not taken.
✗ Branch 723 not taken.
✗ Branch 724 not taken.
✗ Branch 725 not taken.
✗ Branch 726 not taken.
✗ Branch 727 not taken.
✗ Branch 728 not taken.
✗ Branch 729 not taken.
✗ Branch 730 not taken.
✗ Branch 731 not taken.
✗ Branch 732 not taken.
✗ Branch 733 not taken.
✗ Branch 734 not taken.
✗ Branch 735 not taken.
✗ Branch 736 not taken.
✗ Branch 737 not taken.
✗ Branch 738 not taken.
✗ Branch 739 not taken.
✗ Branch 740 not taken.
✗ Branch 741 not taken.
✗ Branch 742 not taken.
✗ Branch 743 not taken.
✗ Branch 744 not taken.
✗ Branch 745 not taken.
✗ Branch 746 not taken.
✗ Branch 747 not taken.
✗ Branch 748 not taken.
✗ Branch 749 not taken.
✗ Branch 750 not taken.
✗ Branch 751 not taken.
✗ Branch 752 not taken.
✗ Branch 753 not taken.
✗ Branch 754 not taken.
✗ Branch 755 not taken.
✗ Branch 756 not taken.
✗ Branch 757 not taken.
✗ Branch 758 not taken.
✗ Branch 759 not taken.
✗ Branch 760 not taken.
✗ Branch 761 not taken.
✗ Branch 762 not taken.
✗ Branch 763 not taken.
✗ Branch 764 not taken.
✗ Branch 765 not taken.
✗ Branch 766 not taken.
✗ Branch 767 not taken.
✗ Branch 768 not taken.
✗ Branch 769 not taken.
✗ Branch 770 not taken.
✗ Branch 771 not taken.
✗ Branch 772 not taken.
✗ Branch 773 not taken.
✗ Branch 774 not taken.
✗ Branch 775 not taken.
✗ Branch 776 not taken.
✗ Branch 777 not taken.
✗ Branch 778 not taken.
✗ Branch 779 not taken.
✗ Branch 780 not taken.
✗ Branch 781 not taken.
✗ Branch 782 not taken.
✗ Branch 783 not taken.
✗ Branch 784 not taken.
✗ Branch 785 not taken.
✗ Branch 786 not taken.
✗ Branch 787 not taken.
✗ Branch 788 not taken.
✗ Branch 789 not taken.
✗ Branch 790 not taken.
✗ Branch 791 not taken.
✗ Branch 792 not taken.
✗ Branch 793 not taken.
✗ Branch 794 not taken.
✗ Branch 795 not taken.
✗ Branch 796 not taken.
✗ Branch 797 not taken.
✗ Branch 798 not taken.
✗ Branch 799 not taken.
✗ Branch 800 not taken.
✗ Branch 801 not taken.
✗ Branch 802 not taken.
✗ Branch 803 not taken.
✗ Branch 804 not taken.
✗ Branch 805 not taken.
✗ Branch 806 not taken.
✗ Branch 807 not taken.
✗ Branch 808 not taken.
✗ Branch 809 not taken.
✗ Branch 810 not taken.
✗ Branch 811 not taken.
✗ Branch 812 not taken.
✗ Branch 813 not taken.
✗ Branch 814 not taken.
✗ Branch 815 not taken.
✗ Branch 816 not taken.
✗ Branch 817 not taken.
✗ Branch 818 not taken.
✗ Branch 819 not taken.
✗ Branch 820 not taken.
✗ Branch 821 not taken.
✗ Branch 822 not taken.
✗ Branch 823 not taken.
✗ Branch 824 not taken.
✗ Branch 825 not taken.
✗ Branch 826 not taken.
✗ Branch 827 not taken.
✗ Branch 828 not taken.
✗ Branch 829 not taken.
✗ Branch 830 not taken.
✗ Branch 831 not taken.
✗ Branch 832 not taken.
✗ Branch 833 not taken.
✗ Branch 834 not taken.
✗ Branch 835 not taken.
✗ Branch 836 not taken.
✓ Branch 837 taken 3182 times.
✗ Branch 838 not taken.
✗ Branch 839 not taken.
✗ Branch 840 not taken.
✗ Branch 841 not taken.
✓ Branch 842 taken 3182 times.
✗ Branch 843 not taken.
✗ Branch 844 not taken.
✗ Branch 845 not taken.
✗ Branch 846 not taken.
✗ Branch 847 not taken.
✗ Branch 848 not taken.
✗ Branch 849 not taken.
✗ Branch 850 not taken.
✗ Branch 851 not taken.
✗ Branch 852 not taken.
✗ Branch 853 not taken.
✗ Branch 854 not taken.
✗ Branch 855 not taken.
✗ Branch 856 not taken.
✓ Branch 857 taken 1 times.
✓ Branch 858 taken 1 times.
✗ Branch 859 not taken.
✗ Branch 860 not taken.
✗ Branch 861 not taken.
✗ Branch 862 not taken.
✗ Branch 863 not taken.
✗ Branch 864 not taken.
✗ Branch 865 not taken.
✗ Branch 866 not taken.
✗ Branch 867 not taken.
✗ Branch 868 not taken.
✗ Branch 869 not taken.
✗ Branch 870 not taken.
✗ Branch 871 not taken.
✗ Branch 872 not taken.
✗ Branch 873 not taken.
✗ Branch 874 not taken.
✗ Branch 875 not taken.
✗ Branch 876 not taken.
✗ Branch 877 not taken.
✗ Branch 878 not taken.
✗ Branch 879 not taken.
✗ Branch 880 not taken.
✓ Branch 881 taken 10 times.
✗ Branch 882 not taken.
✗ Branch 883 not taken.
✗ Branch 884 not taken.
✓ Branch 885 taken 3453 times.
✗ Branch 886 not taken.
✗ Branch 887 not taken.
✗ Branch 888 not taken.
✓ Branch 889 taken 28445 times.
✓ Branch 890 taken 608662 times.
✓ Branch 891 taken 57964044 times.
✓ Branch 892 taken 2054459 times.
✓ Branch 893 taken 5970308 times.
✓ Branch 894 taken 32182962 times.
✓ Branch 895 taken 2 times.
✗ Branch 896 not taken.
✓ Branch 897 taken 22 times.
✓ Branch 898 taken 5774191 times.
✗ Branch 899 not taken.
✓ Branch 900 taken 5603 times.
✓ Branch 901 taken 10 times.
✓ Branch 902 taken 2 times.
✓ Branch 903 taken 549329 times.
✗ Branch 904 not taken.
✓ Branch 905 taken 54 times.
✓ Branch 906 taken 10 times.
✗ Branch 907 not taken.
✗ Branch 908 not taken.
✓ Branch 909 taken 137831 times.
✗ Branch 910 not taken.
✗ Branch 911 not taken.
✗ Branch 912 not taken.
✓ Branch 913 taken 91 times.
✗ Branch 914 not taken.
✗ Branch 915 not taken.
✗ Branch 916 not taken.
✗ Branch 917 not taken.
✓ Branch 918 taken 734476 times.
✓ Branch 919 taken 1156 times.
✗ Branch 920 not taken.
✗ Branch 921 not taken.
✗ Branch 922 not taken.
✓ Branch 923 taken 267249 times.
✗ Branch 924 not taken.
✗ Branch 925 not taken.
✗ Branch 926 not taken.
✓ Branch 927 taken 7555 times.
✗ Branch 928 not taken.
✗ Branch 929 not taken.
✗ Branch 930 not taken.
✗ Branch 931 not taken.
✗ Branch 932 not taken.
✗ Branch 933 not taken.
✗ Branch 934 not taken.
✗ Branch 935 not taken.
✗ Branch 936 not taken.
✗ Branch 937 not taken.
✗ Branch 938 not taken.
✗ Branch 939 not taken.
✗ Branch 940 not taken.
✗ Branch 941 not taken.
✗ Branch 942 not taken.
✗ Branch 943 not taken.
✗ Branch 944 not taken.
✗ Branch 945 not taken.
✗ Branch 946 not taken.
✗ Branch 947 not taken.
✗ Branch 948 not taken.
✗ Branch 949 not taken.
✗ Branch 950 not taken.
✗ Branch 951 not taken.
✗ Branch 952 not taken.
✗ Branch 953 not taken.
✗ Branch 954 not taken.
✗ Branch 955 not taken.
✗ Branch 956 not taken.
✗ Branch 957 not taken.
✓ Branch 958 taken 47730 times.
✗ Branch 959 not taken.
✗ Branch 960 not taken.
✗ Branch 961 not taken.
✗ Branch 962 not taken.
✓ Branch 963 taken 54674 times.
✓ Branch 964 taken 11 times.
✗ Branch 965 not taken.
✗ Branch 966 not taken.
✗ Branch 967 not taken.
✗ Branch 968 not taken.
✗ Branch 969 not taken.
✗ Branch 970 not taken.
✗ Branch 971 not taken.
✗ Branch 972 not taken.
✗ Branch 973 not taken.
✗ Branch 974 not taken.
✗ Branch 975 not taken.
✓ Branch 976 taken 5031 times.
✗ Branch 977 not taken.
✗ Branch 978 not taken.
✗ Branch 979 not taken.
✗ Branch 980 not taken.
✓ Branch 981 taken 1005 times.
✗ Branch 982 not taken.
✓ Branch 983 taken 17326 times.
✓ Branch 984 taken 6024 times.
✗ Branch 985 not taken.
✓ Branch 986 taken 4206 times.
✓ Branch 987 taken 9836 times.
✗ Branch 988 not taken.
✗ Branch 989 not taken.
✓ Branch 990 taken 339 times.
✓ Branch 991 taken 339 times.
✗ Branch 992 not taken.
✗ Branch 993 not taken.
✗ Branch 994 not taken.
✗ Branch 995 not taken.
✗ Branch 996 not taken.
✗ Branch 997 not taken.
✗ Branch 998 not taken.
✗ Branch 999 not taken.
✗ Branch 1000 not taken.
✗ Branch 1001 not taken.
✗ Branch 1002 not taken.
✗ Branch 1003 not taken.
✗ Branch 1004 not taken.
✗ Branch 1005 not taken.
✗ Branch 1006 not taken.
✗ Branch 1007 not taken.
✗ Branch 1008 not taken.
✗ Branch 1009 not taken.
✗ Branch 1010 not taken.
✗ Branch 1011 not taken.
✗ Branch 1012 not taken.
✗ Branch 1013 not taken.
✗ Branch 1014 not taken.
✗ Branch 1015 not taken.
✗ Branch 1016 not taken.
✗ Branch 1017 not taken.
✗ Branch 1018 not taken.
✗ Branch 1019 not taken.
✗ Branch 1020 not taken.
✗ Branch 1021 not taken.
✗ Branch 1022 not taken.
✗ Branch 1023 not taken.
✗ Branch 1024 not taken.
✗ Branch 1025 not taken.
✗ Branch 1026 not taken.
✗ Branch 1027 not taken.
✗ Branch 1028 not taken.
✗ Branch 1029 not taken.
✗ Branch 1030 not taken.
✗ Branch 1031 not taken.
✗ Branch 1032 not taken.
✗ Branch 1033 not taken.
✗ Branch 1034 not taken.
✗ Branch 1035 not taken.
✗ Branch 1036 not taken.
✗ Branch 1037 not taken.
✓ Branch 1038 taken 1455 times.
✗ Branch 1039 not taken.
✗ Branch 1040 not taken.
✗ Branch 1041 not taken.
✗ Branch 1042 not taken.
✗ Branch 1043 not taken.
✗ Branch 1044 not taken.
✗ Branch 1045 not taken.
✗ Branch 1046 not taken.
✗ Branch 1047 not taken.
✗ Branch 1048 not taken.
✗ Branch 1049 not taken.
✗ Branch 1050 not taken.
✗ Branch 1051 not taken.
✗ Branch 1052 not taken.
✗ Branch 1053 not taken.
✗ Branch 1054 not taken.
✗ Branch 1055 not taken.
✗ Branch 1056 not taken.
✗ Branch 1057 not taken.
✗ Branch 1058 not taken.
✗ Branch 1059 not taken.
✗ Branch 1060 not taken.
✗ Branch 1061 not taken.
✗ Branch 1062 not taken.
3241826608 switch(arg)
3030 {
3031 case MAX_FFC_ID:
3032 {
3033 3175268 ret = (MAX_FFCID + 1) * 10000;
3034 3175268 break;
3035 }
3036
3037 case INCQST:
3038 {
3039 int32_t newqst = 0;
3040 if ( game->get_quest() < 255 ) //255 is a custom quest
3041 {
3042 newqst = (game->get_quest()+1);
3043 }
3044 else
3045 {
3046 newqst = 1;
3047 }
3048 if ( newqst < 11 )
3049 {
3050
3051 ret = newqst * 10000;
3052 Quit = qINCQST;
3053 //ending();
3054
3055 }
3056 else ret = -10000;
3057 break;
3058 }
3059 case DEBUGTESTING:
3060 623633 ret = use_testingst_start ? 10000 : 0;
3061 623633 break;
3062
3063 ///----------------------------------------------------------------------------------------------------//
3064 //FFC Variables
3065 case DATA:
3066
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 13073813 times.
13073815 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
3067 13073813 ret = ffc->data * 10000;
3068 13073815 break;
3069
3070 case FFSCRIPT:
3071
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 531424835 times.
531425047 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3072 531424835 ret = ffc->script * 10000;
3073 531425047 break;
3074
3075 case FCSET:
3076
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2312686 times.
2312686 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3077 2312686 ret = ffc->cset * 10000;
3078 2312686 break;
3079
3080 case DELAY:
3081
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3082 10 ret = ffc->delay * 10000;
3083 10 break;
3084
3085 case FX:
3086
1/2
✓ Branch 0 taken 24185371 times.
✗ Branch 1 not taken.
24185371 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3087 24185371 ret = ffc->x.getZLong();
3088 24185371 break;
3089
3090 case FY:
3091
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23746252 times.
23746252 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3092 23746252 ret = ffc->y.getZLong();
3093 23746252 break;
3094
3095 case XD:
3096
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5823966 times.
5823966 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3097 5823966 ret = ffc->vx.getZLong();
3098 5823966 break;
3099
3100 case YD:
3101
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 163102 times.
163102 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3102 163102 ret = ffc->vy.getZLong();
3103 163102 break;
3104 case FFCID:
3105
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 377 times.
377 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
3106 377 ret = (get_region_screen_offset(ffc->screen_spawned) * MAXFFCS + ffc->index + 1) * 10000;
3107 377 break;
3108
3109 case XD2:
3110
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3111 51 ret = ffc->ax.getZLong();
3112 51 break;
3113
3114 case YD2:
3115
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3116 51 ret = ffc->ay.getZLong();
3117 51 break;
3118
3119 case FFCWIDTH:
3120
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 204076 times.
204076 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3121 204076 ret = ffc->hit_width * 10000;
3122 204076 break;
3123
3124 case FFCHEIGHT:
3125
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 199035 times.
199035 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3126 199035 ret = ffc->hit_height * 10000;
3127 199035 break;
3128
3129 case FFTWIDTH:
3130
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5283857 times.
5283857 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3131 5283857 ret = ffc->txsz * 10000;
3132 5283857 break;
3133
3134 case FFTHEIGHT:
3135
1/2
✓ Branch 0 taken 5194596 times.
✗ Branch 1 not taken.
5194596 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3136 5194596 ret = ffc->tysz * 10000;
3137 5194596 break;
3138
3139 case FFCLAYER:
3140 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
3141 ret = ffc->layer * 10000;
3142 break;
3143
3144 case FFLINK:
3145 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3146 ret = ffc->link * 10000;
3147 break;
3148
3149 ///----------------------------------------------------------------------------------------------------//
3150 //Hero's Variables
3151 case LINKX:
3152 {
3153
2/2
✓ Branch 0 taken 8978778 times.
✓ Branch 1 taken 35567862 times.
44546640 if (get_qr(qr_SPRITEXY_IS_FLOAT))
3154 {
3155 8978778 ret = Hero.getX().getZLong();
3156 8978778 }
3157 35567862 else ret = int32_t(Hero.getX()) * 10000;
3158
3159 44546640 break;
3160 }
3161
3162 case LINKCSET:
3163 {
3164 ret = Hero.cs * 10000;
3165 break;
3166 }
3167 case LINKY:
3168 {
3169
2/2
✓ Branch 0 taken 9795307 times.
✓ Branch 1 taken 36462843 times.
46258150 if (get_qr(qr_SPRITEXY_IS_FLOAT))
3170 {
3171 9795307 ret = Hero.getY().getZLong();
3172 9795307 }
3173 36462843 else ret = int32_t(Hero.getY()) * 10000;
3174
3175 46258150 break;
3176 }
3177 case LINKZ:
3178 {
3179
2/2
✓ Branch 0 taken 2849746 times.
✓ Branch 1 taken 1200762 times.
4050508 if (get_qr(qr_SPRITEXY_IS_FLOAT))
3180 {
3181 2849746 ret = Hero.getZ().getZLong();
3182 2849746 }
3183 1200762 else ret = int32_t(Hero.getZ()) * 10000;
3184
3185 4050508 break;
3186 }
3187 case LINKJUMP:
3188 722055 ret = Hero.getJump().getZLong();
3189 722055 break;
3190
3191 case HEROFAKEJUMP:
3192 ret = Hero.getFakeJump().getZLong() / -100;
3193 break;
3194
3195 case LINKDIR:
3196 9096958 ret=(int32_t)(Hero.dir)*10000;
3197 9096958 break;
3198
3199 case LINKHITDIR:
3200 441276 ret=(int32_t)(Hero.getHitDir())*10000;
3201 441276 break;
3202
3203 case LINKHP:
3204 27115597 ret=(int32_t)(game->get_life())*10000;
3205 27115597 break;
3206
3207 case LINKGRAVITY:
3208 ret = ( (Hero.moveflags & move_obeys_grav) ? 10000 : 0 );
3209 break;
3210
3211 case HERONOSTEPFORWARD:
3212 ret = ( (FFCore.nostepforward) ? 10000 : 0 );
3213 break;
3214
3215 case LINKMP:
3216 3407280 ret=(int32_t)(game->get_magic())*10000;
3217 3407280 break;
3218
3219 case LINKMAXHP:
3220 1063999 ret=(int32_t)(game->get_maxlife())*10000;
3221 1063999 break;
3222
3223 case LINKMAXMP:
3224 944878 ret=(int32_t)(game->get_maxmagic())*10000;
3225 944878 break;
3226
3227 case LINKACTION:
3228 {
3229 97951537 ret = FFCore.getHeroAction() * 10000;
3230 97951537 break;
3231 }
3232
3233 case HEROHEALTHBEEP:
3234 {
3235 ret = heart_beep ? ( heart_beep_timer * 10000 ) : 0;
3236 break;
3237 }
3238
3239 case LINKHELD:
3240 204 ret = (int32_t)(Hero.getHeldItem())*10000;
3241 204 break;
3242
3243 case HEROSTEPRATE:
3244 12148 ret = Hero.getStepRate() * 10000;
3245 12148 break;
3246 case HEROSHOVEOFFSET:
3247 ret = Hero.shove_offset.getZLong();
3248 break;
3249
3250 case LINKEQUIP:
3251 1249005 ret = ((Awpn&0xFF)|((Bwpn&0xFF)<<8))*10000;
3252 1249005 break;
3253
3254 case LINKINVIS:
3255 837632 ret = (((int32_t)(Hero.getDontDraw())) ? 10000 : 0);
3256 837632 break;
3257
3258 case LINKINVINC:
3259 654959 ret = (int32_t)(Hero.scriptcoldet)*10000;
3260 654959 break;
3261
3262 case LINKENGINEANIMATE:
3263 ret = (int32_t)(Hero.do_animation)*10000;
3264 break;
3265
3266 case LINKLADDERX:
3267 ret=(int32_t)(Hero.getLadderX())*10000;
3268 break;
3269
3270 case LINKLADDERY:
3271 ret=(int32_t)(Hero.getLadderY())*10000;
3272 break;
3273
3274 case LINKSWORDJINX:
3275 2161763 ret = (int32_t)(Hero.getSwordClk())*10000;
3276 2161763 break;
3277
3278 case LINKITEMJINX:
3279 1095514 ret = (int32_t)(Hero.getItemClk())*10000;
3280 1095514 break;
3281
3282 case LINKDRUNK:
3283 ret = (int32_t)(Hero.DrunkClock())*10000;
3284 break;
3285
3286 case LINKROTATION:
3287 if ( get_qr(qr_OLDSPRITEDRAWS) )
3288 {
3289 scripting_log_error_with_context("To use this you must disable the quest rule 'Old (Faster) Sprite Drawing'.");
3290 ret = -1; break;
3291 }
3292 ret = (int32_t)(Hero.rotation)*10000;
3293 break;
3294
3295 case LINKSCALE:
3296 {
3297 if ( get_qr(qr_OLDSPRITEDRAWS) )
3298 {
3299 scripting_log_error_with_context("To use this you must disable the quest rule 'Old (Faster) Sprite Drawing'.");
3300 ret = -1; break;
3301 }
3302 ret = (int32_t)(Hero.scale*100.0);
3303 break;
3304 }
3305
3306
3307 case LINKHXOFS:
3308 656387 ret = (int32_t)(Hero.hxofs)*10000;
3309 656387 break;
3310
3311 case LINKHYOFS:
3312 571655 ret = (int32_t)(Hero.hyofs)*10000;
3313 571655 break;
3314
3315 case LINKXOFS:
3316 113145 ret = (int32_t)(Hero.xofs)*10000;
3317 113145 break;
3318
3319 case LINKYOFS:
3320
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 115547 times.
115547 ret = (int32_t)(Hero.yofs-(get_qr(qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset))*10000;
3321 115547 break;
3322
3323 case HEROSHADOWXOFS:
3324 ret = (int32_t)(Hero.shadowxofs)*10000;
3325 break;
3326
3327 case HEROSHADOWYOFS:
3328 ret = (int32_t)(Hero.shadowyofs)*10000;
3329 break;
3330
3331 case HEROTOTALDYOFFS:
3332 ret = 10000*(((int32_t)(Hero.yofs-(get_qr(qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset)))
3333 + ((Hero.switch_hooked && Hero.switchhookstyle == swRISE)
3334 ? -(8-(abs(Hero.switchhookclk-32)/4)) : 0));
3335 break;
3336
3337 case LINKZOFS:
3338 ret = (int32_t)(Hero.zofs)*10000;
3339 break;
3340
3341 case LINKHXSZ:
3342 489104 ret = (int32_t)(Hero.hit_width)*10000;
3343 489104 break;
3344
3345 case LINKHYSZ:
3346 489104 ret = (int32_t)(Hero.hit_height)*10000;
3347 489104 break;
3348
3349 case LINKHZSZ:
3350 288295 ret = (int32_t)(Hero.hzsz)*10000;
3351 288295 break;
3352
3353 case LINKTXSZ:
3354 ret = (int32_t)(Hero.txsz)*10000;
3355 break;
3356
3357 case LINKTYSZ:
3358 ret = (int32_t)(Hero.tysz)*10000;
3359 break;
3360
3361 case LINKTILE:
3362 4101 ret = (int32_t)(Hero.tile)*10000;
3363 4101 break;
3364
3365 case LINKFLIP:
3366 ret = (int32_t)(Hero.flip)*10000;
3367 break;
3368
3369 case LINKINVFRAME:
3370 57322 ret = (int32_t)Hero.getHClk()*10000;
3371 57322 break;
3372
3373 case LINKCANFLICKER:
3374 ret= Hero.getCanFlicker()?10000:0;
3375 break;
3376 case LINKHURTSFX:
3377 ret = (int32_t)Hero.getHurtSFX()*10000;
3378 break;
3379
3380 /*
3381 case LINKUSINGITEM:
3382 ret = (int32_t)Hero.getDirectItem()*10000;
3383 break;
3384
3385 case LINKUSINGITEMA:
3386 ret = (int32_t)Hero.getDirectItemA()*10000;
3387 break;
3388
3389 case LINKUSINGITEMB:
3390 ret = (int32_t)Hero.getDirectItemB()*10000;
3391 break;
3392 */
3393
3394 case LINKEATEN:
3395 ret=(int32_t)Hero.getEaten()*10000;
3396 break;
3397 case LINKGRABBED:
3398 ret = Hero.inwallm ? 10000 : 0;
3399 break;
3400 case HEROBUNNY:
3401 ret = Hero.BunnyClock()*10000;
3402 break;
3403 case LINKPUSH:
3404 180367 ret=(int32_t)Hero.getPushing()*10000;
3405 180367 break;
3406 case LINKSTUN:
3407 440896 ret=(int32_t)Hero.StunClock()*10000;
3408 440896 break;
3409 case LINKSCRIPTTILE:
3410 2 ret=script_hero_sprite*10000;
3411 2 break;
3412
3413 case HEROSCRIPTCSET:
3414 ret=script_hero_cset*10000;
3415 break;
3416 case LINKSCRIPFLIP:
3417 ret=script_hero_flip*10000;
3418 break;
3419
3420
3421 case LINKITEMB:
3422 //Hero->setBButtonItem(vbound((value/10000),0,(MAXITEMS-1)));
3423 429515 ret = Bwpn*10000;
3424 429515 break;
3425
3426 case LINKITEMA:
3427 //Hero->setBButtonItem(vbound((value/10000),0,(MAXITEMS-1)));
3428 433515 ret = Awpn *10000;
3429 433515 break;
3430
3431 case LINKITEMX:
3432 //Hero->setBButtonItem(vbound((value/10000),0,(MAXITEMS-1)));
3433 337540 ret = Xwpn *10000;
3434 337540 break;
3435
3436 case LINKITEMY:
3437 //Hero->setBButtonItem(vbound((value/10000),0,(MAXITEMS-1)));
3438 274017 ret = Ywpn *10000;
3439 274017 break;
3440
3441 case LINKTILEMOD:
3442 ret = Hero.getTileModifier() * 10000;
3443 break;
3444
3445 case LINKDIAG:
3446 ret=Hero.getDiagMove()?10000:0;
3447 break;
3448
3449 case LINKBIGHITBOX:
3450 271788 ret=Hero.getBigHitbox()?10000:0;
3451 271788 break;
3452
3453 case LINKCLIMBING:
3454 ret = Hero.getOnSideviewLadder()?10000:0;
3455 break;
3456
3457 case HEROJUMPCOUNT:
3458 ret = Hero.extra_jump_count * 10000;
3459 break;
3460
3461 case HEROPULLDIR:
3462 ret = Hero.pit_pulldir * 10000;
3463 break;
3464
3465 case HEROPULLCLK:
3466 ret = Hero.pit_pullclk * 10000;
3467 break;
3468
3469 case HEROFALLCLK:
3470 834841 ret = Hero.fallclk * 10000;
3471 834841 break;
3472
3473 case HEROFALLCMB:
3474 18 ret = Hero.fallCombo * 10000;
3475 18 break;
3476
3477 case HERODROWNCLK:
3478 ret = Hero.drownclk * 10000;
3479 break;
3480
3481 case HERODROWNCMB:
3482 ret = Hero.drownCombo * 10000;
3483 break;
3484
3485 case HEROFAKEZ:
3486 {
3487
1/2
✓ Branch 0 taken 4357 times.
✗ Branch 1 not taken.
4357 if (get_qr(qr_SPRITEXY_IS_FLOAT))
3488 {
3489 4357 ret = Hero.getFakeZ().getZLong();
3490 4357 }
3491 else ret = int32_t(Hero.getFakeZ()) * 10000;
3492
3493 4357 break;
3494 }
3495
3496 case HEROSHIELDJINX:
3497 ret = Hero.shieldjinxclk * 10000;
3498 break;
3499
3500 case HEROISWARPING:
3501 13171261 ret = Hero.is_warping ? 10000L : 0L;
3502 13171261 break;
3503
3504 case CLOCKACTIVE:
3505 ret=watch?10000:0;
3506 break;
3507
3508 case CLOCKCLK:
3509 ret=clockclk*10000;
3510 break;
3511
3512 case HERORESPAWNX:
3513 {
3514 ret = Hero.respawn_x.getZLong();
3515 break;
3516 }
3517
3518 case HERORESPAWNY:
3519 {
3520 ret = Hero.respawn_y.getZLong();
3521 break;
3522 }
3523
3524 case HERORESPAWNDMAP:
3525 {
3526 ret = Hero.respawn_dmap * 10000;
3527 break;
3528 }
3529
3530 case HERORESPAWNSCR:
3531 {
3532 ret = Hero.respawn_scr * 10000;
3533 break;
3534 }
3535
3536 case HEROSWITCHTIMER:
3537 {
3538 ret = Hero.switchhookclk * 10000;
3539 break;
3540 }
3541
3542 case HEROSWITCHMAXTIMER:
3543 {
3544 ret = Hero.switchhookmaxtime * 10000;
3545 break;
3546 }
3547
3548 case HEROIMMORTAL:
3549 {
3550 ret = Hero.immortal * 10000;
3551 break;
3552 }
3553
3554 case HEROSTANDING:
3555 {
3556 ret = Hero.isStanding(true) ? 10000 : 0;
3557 break;
3558 }
3559
3560 case HEROCOYOTETIME:
3561 {
3562 ret = Hero.coyotetime*10000;
3563 break;
3564 }
3565
3566 case HEROLIFTEDWPN:
3567 {
3568 ret = Hero.lift_wpn ? Hero.lift_wpn->getUID() : 0;
3569 break;
3570 }
3571 case HEROLIFTTIMER:
3572 {
3573 ret = Hero.liftclk * 10000;
3574 break;
3575 }
3576 case HEROLIFTMAXTIMER:
3577 {
3578 ret = Hero.tliftclk * 10000;
3579 break;
3580 }
3581 case HEROLIFTHEIGHT:
3582 {
3583 ret = Hero.liftheight.getZLong();
3584 break;
3585 }
3586 case HEROHAMMERSTATE:
3587 {
3588 ret = Hero.getHammerState() * 10000;
3589 break;
3590 }
3591 case HEROFLICKERCOLOR:
3592 ret = (int32_t)(Hero.flickercolor) * 10000; break;
3593 case HEROFLASHINGCSET:
3594 136185 ret = (int32_t)(Hero.getFlashingCSet()) * 10000; break;
3595 case HEROFLICKERTRANSP:
3596 ret = (int32_t)(Hero.flickertransp) * 10000; break;
3597
3598 case HEROSLIDING:
3599 ret = Hero.sliding*10000; break;
3600 case HEROICECMB:
3601 ret = Hero.ice_combo*10000; break;
3602 case HEROSCRICECMB:
3603 ret = Hero.script_ice_combo*10000; break;
3604 case HEROICEVX:
3605 ret = Hero.ice_vx.getZLong(); break;
3606 case HEROICEVY:
3607 ret = Hero.ice_vy.getZLong(); break;
3608 case HEROICEENTRYFRAMES:
3609 ret = Hero.ice_entry_count*10000; break;
3610 case HEROICEENTRYMAXFRAMES:
3611 ret = Hero.ice_entry_mcount*10000; break;
3612
3613 ///----------------------------------------------------------------------------------------------------//
3614 //Input States
3615 case INPUTSTART:
3616 98023 ret=control_state[6]?10000:0;
3617 98023 break;
3618
3619 case INPUTMAP:
3620 4123 ret=control_state[9]?10000:0;
3621 4123 break;
3622
3623 case INPUTUP:
3624 5056867 ret=control_state[0]?10000:0;
3625 5056867 break;
3626
3627 case INPUTDOWN:
3628 4410418 ret=control_state[1]?10000:0;
3629 4410418 break;
3630
3631 case INPUTLEFT:
3632 4977391 ret=control_state[2]?10000:0;
3633 4977391 break;
3634
3635 case INPUTRIGHT:
3636 5016239 ret=control_state[3]?10000:0;
3637 5016239 break;
3638
3639 case INPUTA:
3640 11970574 ret=control_state[4]?10000:0;
3641 11970574 break;
3642
3643 case INPUTB:
3644 10596134 ret=control_state[5]?10000:0;
3645 10596134 break;
3646
3647 case INPUTL:
3648 6428754 ret=control_state[7]?10000:0;
3649 6428754 break;
3650
3651 case INPUTR:
3652 6424495 ret=control_state[8]?10000:0;
3653 6424495 break;
3654
3655 case INPUTEX1:
3656 122646 ret=control_state[10]?10000:0;
3657 122646 break;
3658
3659 case INPUTEX2:
3660 122937 ret=control_state[11]?10000:0;
3661 122937 break;
3662
3663 case INPUTEX3:
3664 23391 ret=control_state[12]?10000:0;
3665 23391 break;
3666
3667 case INPUTEX4:
3668 23391 ret=control_state[13]?10000:0;
3669 23391 break;
3670
3671 case INPUTAXISUP:
3672 ret=control_state[14]?10000:0;
3673 break;
3674
3675 case INPUTAXISDOWN:
3676 ret=control_state[15]?10000:0;
3677 break;
3678
3679 case INPUTAXISLEFT:
3680 ret=control_state[16]?10000:0;
3681 break;
3682
3683 case INPUTAXISRIGHT:
3684 ret=control_state[17]?10000:0;
3685 break;
3686
3687 case INPUTMOUSEX:
3688 {
3689 1054708 ret=get_mouse_state(0)*10000;
3690 1054708 break;
3691 }
3692
3693 case INPUTMOUSEY:
3694 {
3695 1318385 int32_t mousequakeoffset = 56+((int32_t)(zc::math::Sin((double)(quakeclk*int64_t(2)-frame))*4));
3696
3/4
✓ Branch 0 taken 40365 times.
✓ Branch 1 taken 1278020 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1278020 times.
1318385 int32_t tempoffset = (quakeclk > 0) ? mousequakeoffset : (get_qr(qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
3697 1318385 ret=((get_mouse_state(1)-tempoffset))*10000;
3698 1318385 break;
3699 }
3700
3701 case INPUTMOUSEZ:
3702 ret=(get_mouse_state(2))*10000;
3703 break;
3704
3705 case INPUTMOUSEB:
3706 1073638 ret=(get_mouse_state(3))*10000;
3707 1073638 break;
3708
3709 case INPUTPRESSSTART:
3710 1102950 ret=button_press[6]?10000:0;
3711 1102950 break;
3712
3713 case INPUTPRESSMAP:
3714 335996 ret=button_press[9]?10000:0;
3715 335996 break;
3716
3717 case INPUTPRESSUP:
3718 2151876 ret=button_press[0]?10000:0;
3719 2151876 break;
3720
3721 case INPUTPRESSDOWN:
3722 1578611 ret=button_press[1]?10000:0;
3723 1578611 break;
3724
3725 case INPUTPRESSLEFT:
3726 1805665 ret=button_press[2]?10000:0;
3727 1805665 break;
3728
3729 case INPUTPRESSRIGHT:
3730 1291881 ret=button_press[3]?10000:0;
3731 1291881 break;
3732
3733 case INPUTPRESSA:
3734 4122120 ret=button_press[4]?10000:0;
3735 4122120 break;
3736
3737 case INPUTPRESSB:
3738 3447036 ret=button_press[5]?10000:0;
3739 3447036 break;
3740
3741 case INPUTPRESSL:
3742 3697426 ret=button_press[7]?10000:0;
3743 3697426 break;
3744
3745 case INPUTPRESSR:
3746 3481646 ret=button_press[8]?10000:0;
3747 3481646 break;
3748
3749 case INPUTPRESSEX1:
3750 1779092 ret=button_press[10]?10000:0;
3751 1779092 break;
3752
3753 case INPUTPRESSEX2:
3754 1349984 ret=button_press[11]?10000:0;
3755 1349984 break;
3756
3757 case INPUTPRESSEX3:
3758 833679 ret=button_press[12]?10000:0;
3759 833679 break;
3760
3761 case INPUTPRESSEX4:
3762 669416 ret=button_press[13]?10000:0;
3763 669416 break;
3764
3765 case PRESSAXISUP:
3766 ret=button_press[14]?10000:0;
3767 break;
3768
3769 case PRESSAXISDOWN:
3770 ret=button_press[15]?10000:0;
3771 break;
3772
3773 case PRESSAXISLEFT:
3774 ret=button_press[16]?10000:0;
3775 break;
3776
3777 case PRESSAXISRIGHT:
3778 ret=button_press[17]?10000:0;
3779 break;
3780
3781 case KEYMODIFIERS:
3782 {
3783 ret = (key_shifts*10000);
3784 break;
3785 }
3786
3787 ///----------------------------------------------------------------------------------------------------//
3788 //Itemdata Variables
3789
3790
3791 case IDATAUSEWPN:
3792 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3793 {
3794 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3795 ret = -10000;
3796 break;
3797 }
3798 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.imitate_weapon)*10000;
3799 break;
3800 case IDATAUSEDEF:
3801 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3802 {
3803 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3804 ret = -10000;
3805 break;
3806 }
3807 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.default_defense)*10000;
3808 break;
3809 case IDATAWRANGE:
3810 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3811 {
3812 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3813 ret = -10000;
3814 break;
3815 }
3816 ret=(itemsbuf[GET_REF(itemdataref)].weaprange)*10000;
3817 break;
3818 case IDATAMAGICTIMER:
3819 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3820 {
3821 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3822 ret = -10000;
3823 break;
3824 }
3825 ret=(itemsbuf[GET_REF(itemdataref)].magiccosttimer[0])*10000;
3826 break;
3827 case IDATAMAGICTIMER2:
3828 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3829 {
3830 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3831 ret = -10000;
3832 break;
3833 }
3834 ret=(itemsbuf[GET_REF(itemdataref)].magiccosttimer[1])*10000;
3835 break;
3836
3837 case IDATADURATION:
3838 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3839 {
3840 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3841 ret = -10000;
3842 break;
3843 }
3844 ret=(itemsbuf[GET_REF(itemdataref)].weapduration)*10000;
3845 break;
3846
3847 case IDATADUPLICATES:
3848 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3849 {
3850 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3851 ret = -10000;
3852 break;
3853 }
3854 ret=(itemsbuf[GET_REF(itemdataref)].duplicates)*10000;
3855 break;
3856 case IDATADRAWLAYER:
3857 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3858 {
3859 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3860 ret = -10000;
3861 break;
3862 }
3863 ret=(itemsbuf[GET_REF(itemdataref)].drawlayer)*10000;
3864 break;
3865 case IDATACOLLECTFLAGS:
3866 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3867 {
3868 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3869 ret = 0;
3870 break;
3871 }
3872 ret=(itemsbuf[GET_REF(itemdataref)].collectflags)*10000;
3873 break;
3874 case IDATAWEAPONSCRIPT:
3875 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3876 {
3877 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3878 ret = -10000;
3879 break;
3880 }
3881 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.script)*10000;
3882 break;
3883 case IDATAWEAPHXOFS:
3884 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3885 {
3886 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3887 ret = -10000;
3888 break;
3889 }
3890 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.hxofs)*10000;
3891 break;
3892 case IDATAWEAPHYOFS:
3893 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3894 {
3895 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3896 ret = -10000;
3897 break;
3898 }
3899 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.hyofs)*10000;
3900 break;
3901 case IDATAWEAPHXSZ:
3902 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3903 {
3904 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3905 ret = -10000;
3906 break;
3907 }
3908 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.hxsz)*10000;
3909 break;
3910 case IDATAWEAPHYSZ:
3911 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3912 {
3913 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3914 ret = -10000;
3915 break;
3916 }
3917 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.hysz)*10000;
3918 break;
3919 case IDATAWEAPHZSZ:
3920 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3921 {
3922 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3923 ret = -10000;
3924 break;
3925 }
3926 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.hzsz)*10000;
3927 break;
3928 case IDATAWEAPXOFS:
3929 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3930 {
3931 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3932 ret = -10000;
3933 break;
3934 }
3935 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.xofs)*10000;
3936 break;
3937 case IDATAWEAPYOFS:
3938 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3939 {
3940 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3941 ret = -10000;
3942 break;
3943 }
3944 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.yofs)*10000;
3945 break;
3946 case IDATAHXOFS:
3947 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3948 {
3949 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3950 ret = -10000;
3951 break;
3952 }
3953 ret=(itemsbuf[GET_REF(itemdataref)].hxofs)*10000;
3954 break;
3955 case IDATAHYOFS:
3956 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3957 {
3958 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3959 ret = -10000;
3960 break;
3961 }
3962 ret=(itemsbuf[GET_REF(itemdataref)].hyofs)*10000;
3963 break;
3964 case IDATAHXSZ:
3965 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3966 {
3967 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3968 ret = -10000;
3969 break;
3970 }
3971 ret=(itemsbuf[GET_REF(itemdataref)].hxsz)*10000;
3972 break;
3973 case IDATAHYSZ:
3974 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3975 {
3976 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3977 ret = -10000;
3978 break;
3979 }
3980 ret=(itemsbuf[GET_REF(itemdataref)].hysz)*10000;
3981 break;
3982 case IDATAHZSZ:
3983 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3984 {
3985 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3986 ret = -10000;
3987 break;
3988 }
3989 ret=(itemsbuf[GET_REF(itemdataref)].hzsz)*10000;
3990 break;
3991 case IDATADXOFS:
3992 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3993 {
3994 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3995 ret = -10000;
3996 break;
3997 }
3998 ret=(itemsbuf[GET_REF(itemdataref)].xofs)*10000;
3999 break;
4000 case IDATADYOFS:
4001 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4002 {
4003 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4004 ret = -10000;
4005 break;
4006 }
4007 ret=(itemsbuf[GET_REF(itemdataref)].yofs)*10000;
4008 break;
4009 case IDATATILEW:
4010 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4011 {
4012 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4013 ret = -10000;
4014 break;
4015 }
4016 ret=(itemsbuf[GET_REF(itemdataref)].tilew)*10000;
4017 break;
4018 case IDATATILEH:
4019
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53 times.
53 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4020 {
4021 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4022 ret = -10000;
4023 break;
4024 }
4025 53 ret=(itemsbuf[GET_REF(itemdataref)].tileh)*10000;
4026 53 break;
4027 case IDATAPICKUP:
4028 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4029 {
4030 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4031 ret = -10000;
4032 break;
4033 }
4034 ret=(itemsbuf[GET_REF(itemdataref)].pickup)*10000;
4035 break;
4036 case IDATAOVERRIDEFL:
4037 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4038 {
4039 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4040 ret = 0;
4041 break;
4042 }
4043 ret=(itemsbuf[GET_REF(itemdataref)].overrideFLAGS)*10000;
4044 break;
4045
4046 case IDATATILEWWEAP:
4047 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4048 {
4049 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4050 ret = -10000;
4051 break;
4052 }
4053 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.tilew)*10000;
4054 break;
4055 case IDATATILEHWEAP:
4056 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4057 {
4058 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4059 ret = -10000;
4060 break;
4061 }
4062 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.tileh)*10000;
4063 break;
4064 case IDATAOVERRIDEFLWEAP:
4065 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4066 {
4067 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4068 ret = 0;
4069 break;
4070 }
4071 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.override_flags)*10000;
4072 break;
4073
4074 case IDATATYPE:
4075
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58309993 times.
58309993 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4076 {
4077 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4078 ret = -10000;
4079 break;
4080 }
4081 58309993 ret=(itemsbuf[GET_REF(itemdataref)].type)*10000;
4082 58309993 break;
4083
4084 case IDATALEVEL:
4085
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 668845 times.
668845 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4086 {
4087 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4088 ret = -10000;
4089 break;
4090 }
4091 668845 ret=(itemsbuf[GET_REF(itemdataref)].level)*10000;
4092 668845 break;
4093
4094 case IDATAKEEP:
4095 3 ret = item_flag(item_gamedata);
4096 3 break;
4097
4098 case IDATAAMOUNT:
4099 {
4100 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4101 {
4102 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4103 ret = -10000;
4104 break;
4105 }
4106 int32_t v = itemsbuf[GET_REF(itemdataref)].amount;
4107 ret = ((v&0x4000)?-1:1)*(v & 0x3FFF)*10000;
4108 break;
4109 }
4110 case IDATAGRADUAL:
4111 {
4112 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4113 {
4114 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4115 ret = -10000;
4116 break;
4117 }
4118 ret = (itemsbuf[GET_REF(itemdataref)].amount&0x8000) ? 10000 : 0;
4119 break;
4120 }
4121 case IDATACONSTSCRIPT:
4122 ret = item_flag(item_passive_script);
4123 break;
4124 case IDATASSWIMDISABLED:
4125 ret = item_flag(item_sideswim_disabled);
4126 break;
4127 case IDATABUNNYABLE:
4128 ret = item_flag(item_bunny_enabled);
4129 break;
4130 case IDATAJINXIMMUNE:
4131 ret = item_flag(item_jinx_immune);
4132 break;
4133 case IDATAJINXSWAP:
4134 ret = item_flag(item_flip_jinx);
4135 break;
4136 case IDATAUSEBURNSPR:
4137 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4138 {
4139 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4140 ret = 0;
4141 }
4142 else ret = (itemsbuf[GET_REF(itemdataref)].weap_data.wflags & WFLAG_UPDATE_IGNITE_SPRITE) ? 10000 : 0;
4143 break;
4144
4145 case IDATASETMAX:
4146 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4147 {
4148 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4149 ret = -10000;
4150 break;
4151 }
4152 ret=(itemsbuf[GET_REF(itemdataref)].setmax)*10000;
4153 break;
4154
4155 case IDATAMAX:
4156 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4157 {
4158 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4159 ret = -10000;
4160 break;
4161 }
4162 ret=(itemsbuf[GET_REF(itemdataref)].max)*10000;
4163 break;
4164
4165 case IDATACOUNTER:
4166 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4167 {
4168 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4169 ret = -10000;
4170 break;
4171 }
4172 ret=(itemsbuf[GET_REF(itemdataref)].count)*10000;
4173 break;
4174
4175 case IDATAPSOUND:
4176 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4177 {
4178 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4179 ret = -10000;
4180 break;
4181 }
4182 ret=(itemsbuf[GET_REF(itemdataref)].playsound)*10000;
4183 break;
4184 case IDATAUSESOUND:
4185 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4186 {
4187 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4188 ret = -10000;
4189 break;
4190 }
4191 ret=(itemsbuf[GET_REF(itemdataref)].usesound)*10000;
4192 break;
4193
4194 case IDATAUSESOUND2:
4195 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4196 {
4197 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4198 ret = -10000;
4199 break;
4200 }
4201 ret=(itemsbuf[GET_REF(itemdataref)].usesound2)*10000;
4202 break;
4203
4204 case IDATAPOWER:
4205
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1994 times.
1994 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4206 {
4207 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4208 ret = -10000;
4209 break;
4210 }
4211 1994 ret=(itemsbuf[GET_REF(itemdataref)].power)*10000;
4212 1994 break;
4213
4214 //Get the ID of an item.
4215 case IDATAID:
4216
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1918 times.
1918 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4217 {
4218 ret = -10000;
4219 break;
4220 }
4221 1918 ret=GET_REF(itemdataref)*10000;
4222 1918 break;
4223
4224 //Get the script assigned to an item (active)
4225 case IDATASCRIPT:
4226 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4227 {
4228 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4229 ret = -10000;
4230 break;
4231 }
4232 ret=(itemsbuf[GET_REF(itemdataref)].script)*10000;
4233 break;
4234 case IDATASPRSCRIPT:
4235 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4236 {
4237 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4238 ret = -10000;
4239 break;
4240 }
4241 ret=(itemsbuf[GET_REF(itemdataref)].sprite_script)*10000;
4242 break;
4243 //Hero TIle modifier
4244 case IDATALTM:
4245 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4246 {
4247 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4248 ret = 0;
4249 break;
4250 }
4251 ret=(itemsbuf[GET_REF(itemdataref)].ltm)*10000;
4252 break;
4253 //Pickup script
4254 case IDATAPSCRIPT:
4255 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4256 {
4257 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4258 ret = -10000;
4259 break;
4260 }
4261 ret=(itemsbuf[GET_REF(itemdataref)].collect_script)*10000;
4262 break;
4263 //Pickup string
4264 case IDATAPSTRING:
4265 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4266 {
4267 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4268 ret = -10000;
4269 break;
4270 }
4271 ret=(itemsbuf[GET_REF(itemdataref)].pstring)*10000;
4272 break;
4273 case IDATAPFLAGS:
4274 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4275 {
4276 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4277 ret = 0;
4278 break;
4279 }
4280 ret = (itemsbuf[GET_REF(itemdataref)].pickup_string_flags)*10000;
4281 break;
4282 case IDATAPICKUPLITEMS:
4283 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4284 {
4285 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4286 ret = 0;
4287 break;
4288 }
4289 ret = (itemsbuf[GET_REF(itemdataref)].pickup_litems)*10000;
4290 break;
4291 case IDATAPICKUPLITEMLEVEL:
4292 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4293 {
4294 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4295 ret = 0;
4296 break;
4297 }
4298 ret = (itemsbuf[GET_REF(itemdataref)].pickup_litem_level)*10000;
4299 break;
4300 //Magic cost
4301 case IDATAMAGCOST:
4302 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4303 {
4304 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4305 ret = -10000;
4306 break;
4307 }
4308 ret=(itemsbuf[GET_REF(itemdataref)].cost_amount[0])*10000;
4309 break;
4310 case IDATACOST2:
4311 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4312 {
4313 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4314 ret = -10000;
4315 break;
4316 }
4317 ret=(itemsbuf[GET_REF(itemdataref)].cost_amount[1])*10000;
4318 break;
4319 case IDATACOOLDOWN:
4320 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4321 {
4322 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4323 ret = -10000;
4324 break;
4325 }
4326 ret = (itemsbuf[GET_REF(itemdataref)].cooldown) * 10000;
4327 break;
4328 //cost counter ref
4329 case IDATACOSTCOUNTER:
4330 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4331 {
4332 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4333 ret = -10000;
4334 break;
4335 }
4336 ret=(itemsbuf[GET_REF(itemdataref)].cost_counter[0])*10000;
4337 break;
4338 case IDATACOSTCOUNTER2:
4339 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4340 {
4341 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4342 ret = -10000;
4343 break;
4344 }
4345 ret=(itemsbuf[GET_REF(itemdataref)].cost_counter[1])*10000;
4346 break;
4347 //Min Hearts to Pick Up
4348 case IDATAMINHEARTS:
4349 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4350 {
4351 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4352 ret = -10000;
4353 break;
4354 }
4355 ret=(itemsbuf[GET_REF(itemdataref)].pickup_hearts)*10000;
4356 break;
4357 //Tile used by the item
4358 case IDATATILE:
4359
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55709 times.
55709 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4360 {
4361 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4362 ret = -10000;
4363 break;
4364 }
4365 55709 ret=(itemsbuf[GET_REF(itemdataref)].tile)*10000;
4366 55709 break;
4367 //itemdata->Flash
4368 case IDATAMISC:
4369 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4370 {
4371 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4372 ret = -10000;
4373 break;
4374 }
4375 ret=(itemsbuf[GET_REF(itemdataref)].misc_flags)*10000;
4376 break;
4377 //->CSet
4378 case IDATACSET:
4379
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55684 times.
55684 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4380 {
4381 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4382 ret = -10000;
4383 break;
4384 }
4385
4386 55684 ret = (itemsbuf[GET_REF(itemdataref)].csets&15)*10000;
4387
4388 // If we find quests that broke, use this code.
4389 // if (QHeader.compareVer(2, 55, 9) >= 0)
4390 // ret = (itemsbuf[ri->idata].csets&15)*10000;
4391 // else
4392 // ret = itemsbuf[ri->idata].csets*10000;
4393 55684 break;
4394 case IDATAFLASHCSET:
4395 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4396 {
4397 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4398 ret = -10000;
4399 break;
4400 }
4401 ret=(itemsbuf[GET_REF(itemdataref)].csets>>4)*10000;
4402 break;
4403 //->A.Frames
4404 case IDATAFRAMES:
4405
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63041 times.
63041 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4406 {
4407 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4408 ret = -10000;
4409 break;
4410 }
4411 63041 ret=(itemsbuf[GET_REF(itemdataref)].frames)*10000;
4412 63041 break;
4413 /*
4414 case IDATAFRAME:
4415 ret=(itemsbuf[ri->idata].frame)*10000;
4416 break;
4417 */
4418 //->A.Speed
4419 case IDATAASPEED:
4420
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 142873 times.
142873 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4421 {
4422 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4423 ret = -10000;
4424 break;
4425 }
4426 142873 ret=(itemsbuf[GET_REF(itemdataref)].speed)*10000;
4427 142873 break;
4428 //->Delay
4429 case IDATADELAY:
4430
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 74538 times.
74538 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4431 {
4432 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4433 ret = -10000;
4434 break;
4435 }
4436 74538 ret=(itemsbuf[GET_REF(itemdataref)].delay)*10000;
4437 74538 break;
4438 // teo of this item upgrades
4439 case IDATACOMBINE:
4440 ret = item_flag(item_combine);
4441 break;
4442 //Use item, and get the lower level one
4443 case IDATADOWNGRADE:
4444 ret = item_flag(item_downgrade);
4445 break;
4446 //Only validate the cost, don't charge it
4447 case IDATAVALIDATE:
4448 ret = item_flag(item_validate_only);
4449 break;
4450 case IDATAVALIDATE2:
4451 ret = item_flag(item_validate_only_2);
4452 break;
4453 //->Keep Old
4454 case IDATAKEEPOLD:
4455 ret = item_flag(item_keep_old);
4456 break;
4457 //Use rupees instead of magic
4458 case IDATARUPEECOST:
4459 ret = item_flag(item_rupee_magic);
4460 break;
4461 //Can be eaten
4462 case IDATAEDIBLE:
4463 ret = item_flag(item_edible);
4464 break;
4465 //currently unused
4466 case IDATAFLAGUNUSED:
4467 ret = item_flag(item_unused);
4468 break;
4469 //Gain lower level items when collected
4470 case IDATAGAINLOWER:
4471 ret = item_flag(item_gain_old);
4472 break;
4473
4474 ///----------------------------------------------------------------------------------------------------//
4475 //LWeapon Variables
4476 case LWPNSPECIAL:
4477 if(auto s=checkLWpn(GET_REF(lwpnref)))
4478 ret=((int32_t)s->specialinfo)*10000;
4479
4480
4481 break;
4482
4483 case LWPNSCALE:
4484 if ( get_qr(qr_OLDSPRITEDRAWS) )
4485 {
4486 scripting_log_error_with_context("To use this you must disable the quest rule 'Old (Faster) Sprite Drawing'.");
4487 ret = -1; break;
4488 }
4489 if(auto s=checkLWpn(GET_REF(lwpnref)))
4490 ret=((int32_t)s->scale)*100.0;
4491
4492 break;
4493
4494 case LWPNX:
4495
2/2
✓ Branch 0 taken 15492 times.
✓ Branch 1 taken 939265 times.
954757 if(auto s=checkLWpn(GET_REF(lwpnref)))
4496 {
4497
2/2
✓ Branch 0 taken 350528 times.
✓ Branch 1 taken 588737 times.
939265 if ( get_qr(qr_SPRITEXY_IS_FLOAT) )
4498 {
4499 350528 ret=(s->x).getZLong();
4500 350528 }
4501 else
4502 588737 ret=((int32_t)s->x)*10000;
4503 939265 }
4504
4505 954757 break;
4506
4507 case SPRITEMAXLWPN:
4508 {
4509 //No bounds check, as this is a universal function and works from NULL pointers!
4510 ret = Lwpns.getMax() * 10000;
4511 break;
4512 }
4513
4514 case LWPNY:
4515
2/2
✓ Branch 0 taken 15492 times.
✓ Branch 1 taken 934658 times.
950150 if(auto s=checkLWpn(GET_REF(lwpnref)))
4516 {
4517
2/2
✓ Branch 0 taken 350395 times.
✓ Branch 1 taken 584263 times.
934658 if ( get_qr(qr_SPRITEXY_IS_FLOAT) )
4518 {
4519 350395 ret=(s->y).getZLong();
4520 350395 }
4521 else
4522 584263 ret=((int32_t)s->y)*10000;
4523 934658 }
4524 950150 break;
4525
4526 case LWPNZ:
4527
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 109736 times.
109736 if(auto s=checkLWpn(GET_REF(lwpnref)))
4528 {
4529
2/2
✓ Branch 0 taken 53984 times.
✓ Branch 1 taken 55752 times.
109736 if ( get_qr(qr_SPRITEXY_IS_FLOAT) )
4530 {
4531 53984 ret=(s->z).getZLong();
4532 53984 }
4533 else
4534 55752 ret=((int32_t)s->z)*10000;
4535 109736 }
4536
4537 109736 break;
4538
4539 case LWPNJUMP:
4540
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
4541 {
4542 6 ret = s->fall.getZLong() / -100;
4543
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (get_qr(qr_SPRITE_JUMP_IS_TRUNCATED)) ret = trunc(ret / 10000) * 10000;
4544 6 }
4545
4546 6 break;
4547
4548 case LWPNFAKEJUMP:
4549 if(auto s=checkLWpn(GET_REF(lwpnref)))
4550 {
4551 ret = s->fakefall.getZLong() / -100;
4552 if (get_qr(qr_SPRITE_JUMP_IS_TRUNCATED)) ret = trunc(ret / 10000) * 10000;
4553 }
4554
4555 break;
4556
4557 case LWPNDIR:
4558
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80933 times.
80933 if(auto s=checkLWpn(GET_REF(lwpnref)))
4559 80933 ret=s->dir*10000;
4560
4561 80933 break;
4562
4563 case LWPNGRAVITY:
4564 if(auto s=checkLWpn(GET_REF(lwpnref)))
4565 ret= (s->moveflags & move_obeys_grav) ? 10000 : 0;
4566
4567 break;
4568
4569 case LWPNSTEP:
4570
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5388 times.
5388 if(auto s=checkLWpn(GET_REF(lwpnref)))
4571 {
4572
3/4
✓ Branch 0 taken 1140 times.
✓ Branch 1 taken 4248 times.
✓ Branch 2 taken 1140 times.
✗ Branch 3 not taken.
5388 if ( get_qr(qr_STEP_IS_FLOAT) || replay_is_active() )
4573 {
4574 5388 ret=s->step.getZLong() * 100;
4575 5388 }
4576 //old, buggy code replication, round two: Go! -Z
4577 //else ret = ( ( ( s->step ) * 100.0 ).getZLong() );
4578
4579 //else
4580 //{
4581 //old, buggy code replication, round THREE: Go! -Z
4582 // double tmp = ( s->step.getFloat() ) * 1000000.0;
4583 // ret = (int32_t)tmp;
4584 //}
4585
4586 //old, buggy code replication, round FOUR: Go! -Z
4587 else ret = (int32_t)((float)s->step * 1000000.0);
4588 5388 }
4589 5388 break;
4590
4591 case LWPNANGLE:
4592
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 416 times.
416 if(auto s=checkLWpn(GET_REF(lwpnref)))
4593 416 ret=(int32_t)(s->angle*10000);
4594
4595 416 break;
4596
4597 case LWPNDEGANGLE:
4598 if(auto s=checkLWpn(GET_REF(lwpnref)))
4599 {
4600 ret=(int32_t)(s->angle*(180.0 / PI)*10000);
4601 }
4602
4603 break;
4604
4605 case LWPNVX:
4606
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 246 times.
246 if(auto s=checkLWpn(GET_REF(lwpnref)))
4607 {
4608
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 246 times.
246 if (s->angular)
4609 ret = int32_t(zc::math::Cos(s->angle)*10000.0*s->step);
4610 else
4611 {
4612
4/7
✓ Branch 0 taken 246 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 246 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 122 times.
✓ Branch 6 taken 124 times.
246 switch(NORMAL_DIR(s->dir))
4613 {
4614 case l_up:
4615 case l_down:
4616 case left:
4617 ret = int32_t(-10000.0*s->step);
4618 break;
4619
4620 case r_down:
4621 case r_up:
4622 case right:
4623 122 ret = int32_t(10000.0*s->step);
4624 122 break;
4625
4626 default:
4627 124 ret = 0;
4628 124 break;
4629 }
4630 }
4631 246 }
4632
4633 246 break;
4634
4635 case LWPNVY:
4636 if(auto s=checkLWpn(GET_REF(lwpnref)))
4637 {
4638 if (s->angular)
4639 ret = int32_t(zc::math::Sin(s->angle)*10000.0*s->step);
4640 else
4641 {
4642 switch(NORMAL_DIR(s->dir))
4643 {
4644 case l_up:
4645 case r_up:
4646 case up:
4647 ret = int32_t(-10000.0*s->step);
4648 break;
4649 case l_down:
4650 case r_down:
4651 case down:
4652 ret = int32_t(10000.0*s->step);
4653 break;
4654
4655 default:
4656 ret = 0;
4657 break;
4658 }
4659 }
4660 }
4661
4662 break;
4663
4664 case LWPNANGULAR:
4665
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
4666 6 ret=s->angular*10000;
4667
4668 6 break;
4669
4670 case LWPNAUTOROTATE:
4671 if(auto s=checkLWpn(GET_REF(lwpnref)))
4672 ret=s->autorotate*10000;
4673
4674 break;
4675
4676 case LWPNBEHIND:
4677 if(auto s=checkLWpn(GET_REF(lwpnref)))
4678 ret=s->behind*10000;
4679
4680 break;
4681
4682 case LWPNDRAWTYPE:
4683
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
4684 6 ret=s->drawstyle*10000;
4685
4686 6 break;
4687
4688 case LWPNPOWER:
4689
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 104530 times.
104531 if(auto s=checkLWpn(GET_REF(lwpnref)))
4690 104530 ret=s->power*10000;
4691
4692 104531 break;
4693
4694 case LWPNDEAD:
4695
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8339 times.
8339 if(auto s=checkLWpn(GET_REF(lwpnref)))
4696 8339 ret=s->dead*10000;
4697
4698 8339 break;
4699
4700 case LWPNTYPE:
4701
2/2
✓ Branch 0 taken 16620 times.
✓ Branch 1 taken 4500566 times.
4517186 if(auto s=checkLWpn(GET_REF(lwpnref)))
4702 4500566 ret=s->id*10000;
4703
4704 4517186 break;
4705
4706 case LWPNTILE:
4707
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53697 times.
53697 if(auto s=checkLWpn(GET_REF(lwpnref)))
4708 53697 ret=s->tile*10000;
4709
4710 53697 break;
4711
4712 case LWPNSCRIPTTILE:
4713
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 586 times.
586 if(auto s=checkLWpn(GET_REF(lwpnref)))
4714 586 ret=s->scripttile*10000;
4715
4716 586 break;
4717
4718 case LWPNSCRIPTFLIP:
4719 if(auto s=checkLWpn(GET_REF(lwpnref)))
4720 ret=s->scriptflip*10000;
4721
4722 break;
4723
4724 case LWPNCSET:
4725
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53381 times.
53381 if(auto s=checkLWpn(GET_REF(lwpnref)))
4726 53381 ret=s->cs*10000;
4727
4728 53381 break;
4729
4730 case LWPNFLASHCSET:
4731
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 220 times.
220 if(auto s=checkLWpn(GET_REF(lwpnref)))
4732 220 ret=(s->o_cset>>4)*10000;
4733
4734 220 break;
4735
4736 case LWPNFRAMES:
4737
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4362 times.
4362 if(auto s=checkLWpn(GET_REF(lwpnref)))
4738 4362 ret=s->frames*10000;
4739
4740 4362 break;
4741
4742 case LWPNFRAME:
4743
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
4744 6 ret=s->aframe*10000;
4745
4746 6 break;
4747
4748 case LWPNASPEED:
4749
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4622 times.
4622 if(auto s=checkLWpn(GET_REF(lwpnref)))
4750 4622 ret=s->o_speed*10000;
4751
4752 4622 break;
4753
4754 case LWPNFLASH:
4755
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
4756 6 ret=s->flash*10000;
4757
4758 6 break;
4759
4760 case LWPNFLIP:
4761 if(auto s=checkLWpn(GET_REF(lwpnref)))
4762 ret=s->flip*10000;
4763
4764 break;
4765
4766 case LWPNCOUNT:
4767 2001860 ret=Lwpns.Count()*10000;
4768 2001860 break;
4769
4770 case LWPNEXTEND:
4771
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
4772 6 ret=s->extend*10000;
4773
4774 6 break;
4775
4776 case LWPNOTILE:
4777
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 835937 times.
835937 if(auto s=checkLWpn(GET_REF(lwpnref)))
4778 835937 ret=s->o_tile*10000;
4779
4780 835937 break;
4781
4782 case LWPNOCSET:
4783
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23909 times.
23909 if(auto s=checkLWpn(GET_REF(lwpnref)))
4784 23909 ret=(s->o_cset&15)*10000;
4785
4786 23909 break;
4787
4788 case LWPNHXOFS:
4789
2/2
✓ Branch 0 taken 15492 times.
✓ Branch 1 taken 284226 times.
299718 if(auto s=checkLWpn(GET_REF(lwpnref)))
4790 284226 ret=(s->hxofs)*10000;
4791
4792 299718 break;
4793
4794 case LWPNHYOFS:
4795
2/2
✓ Branch 0 taken 15492 times.
✓ Branch 1 taken 281478 times.
296970 if(auto s=checkLWpn(GET_REF(lwpnref)))
4796 281478 ret=(s->hyofs)*10000;
4797
4798 296970 break;
4799
4800 case LWPNXOFS:
4801
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10231 times.
10231 if(auto s=checkLWpn(GET_REF(lwpnref)))
4802 10231 ret=((int32_t)(s->xofs))*10000;
4803
4804 10231 break;
4805
4806 case LWPNYOFS:
4807
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11477 times.
11477 if(auto s=checkLWpn(GET_REF(lwpnref)))
4808
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11477 times.
11477 ret=((int32_t)(s->yofs-(get_qr(qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset)))*10000;
4809
4810 11477 break;
4811
4812 case LWPNSHADOWXOFS:
4813 if(auto s=checkLWpn(GET_REF(lwpnref)))
4814 ret=((int32_t)(s->shadowxofs))*10000;
4815
4816 break;
4817
4818 case LWPNSHADOWYOFS:
4819 if(auto s=checkLWpn(GET_REF(lwpnref)))
4820 ret=((int32_t)(s->shadowyofs))*10000;
4821
4822 break;
4823
4824 case LWPNTOTALDYOFFS:
4825 if(auto s=checkLWpn(GET_REF(lwpnref)))
4826 ret = ((int32_t)(s->yofs-(get_qr(qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset))
4827 + ((s->switch_hooked && Hero.switchhookstyle == swRISE)
4828 ? -(8-(abs(Hero.switchhookclk-32)/4)) : 0)) * 10000;
4829 break;
4830
4831 case LWPNZOFS:
4832
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
4833 6 ret=((int32_t)(s->zofs))*10000;
4834
4835 6 break;
4836
4837 case LWPNHXSZ:
4838
2/2
✓ Branch 0 taken 267550 times.
✓ Branch 1 taken 15492 times.
283042 if(auto s=checkLWpn(GET_REF(lwpnref)))
4839 267550 ret=(s->hit_width)*10000;
4840
4841 283042 break;
4842
4843 case LWPNHYSZ:
4844
2/2
✓ Branch 0 taken 269504 times.
✓ Branch 1 taken 15492 times.
284996 if(auto s=checkLWpn(GET_REF(lwpnref)))
4845 269504 ret=(s->hit_height)*10000;
4846
4847 284996 break;
4848
4849 case LWPNHZSZ:
4850
1/2
✓ Branch 0 taken 36540 times.
✗ Branch 1 not taken.
36540 if(auto s=checkLWpn(GET_REF(lwpnref)))
4851 36540 ret=(s->hzsz)*10000;
4852
4853 36540 break;
4854
4855 case LWPNTXSZ:
4856
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32019 times.
32019 if(auto s=checkLWpn(GET_REF(lwpnref)))
4857 32019 ret=(s->txsz)*10000;
4858
4859 32019 break;
4860
4861 case LWPNTYSZ:
4862
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32019 times.
32019 if(auto s=checkLWpn(GET_REF(lwpnref)))
4863 32019 ret=(s->tysz)*10000;
4864
4865 32019 break;
4866
4867 case LWPNCOLLDET:
4868
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5469 times.
5469 if(auto s=checkLWpn(GET_REF(lwpnref)))
4869 5469 ret=(s->scriptcoldet)*10000;
4870
4871 5469 break;
4872
4873 case LWPNENGINEANIMATE:
4874 if(auto s=checkLWpn(GET_REF(lwpnref)))
4875 ret=(s->do_animation)*10000;
4876
4877 break;
4878
4879 case LWPNPARENT:
4880
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2166 times.
2166 if(auto s=checkLWpn(GET_REF(lwpnref)))
4881 2166 ret=(s->parentitem)*10000;
4882
4883 2166 break;
4884
4885 case LWPNLEVEL:
4886 if(auto s=checkLWpn(GET_REF(lwpnref)))
4887 ret=(s->level)*10000;
4888
4889 break;
4890
4891 case LWPNSCRIPT:
4892
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if(auto s=checkLWpn(GET_REF(lwpnref)))
4893 3 ret=(s->script)*10000;
4894
4895 3 break;
4896
4897 case LWPNUSEWEAPON:
4898
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60075 times.
60075 if(auto s=checkLWpn(GET_REF(lwpnref)))
4899 60075 ret=(s->useweapon)*10000;
4900
4901 60075 break;
4902
4903 case LWPNUSEDEFENCE:
4904 if(auto s=checkLWpn(GET_REF(lwpnref)))
4905 ret=(s->usedefense)*10000;
4906
4907 break;
4908
4909 case LWEAPONSCRIPTUID:
4910 if(auto s=checkLWpn(GET_REF(lwpnref)))
4911 ret=(s->getUID());
4912
4913 break;
4914
4915 case LWPNROTATION:
4916 if ( get_qr(qr_OLDSPRITEDRAWS) )
4917 {
4918 scripting_log_error_with_context("To use this you must disable the quest rule 'Old (Faster) Sprite Drawing'.");
4919 ret = -1; break;
4920 }
4921 if(auto s=checkLWpn(GET_REF(lwpnref)))
4922 ret=s->rotation*10000;
4923
4924 break;
4925
4926 case LWPNFALLCLK:
4927
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1552 times.
1552 if(auto s=checkLWpn(GET_REF(lwpnref)))
4928 {
4929 1552 ret = s->fallclk * 10000;
4930 1552 }
4931 1552 break;
4932
4933 case LWPNFALLCMB:
4934 if(auto s=checkLWpn(GET_REF(lwpnref)))
4935 {
4936 ret = s->fallCombo * 10000;
4937 }
4938 break;
4939
4940 case LWPNDROWNCLK:
4941 if(auto s=checkLWpn(GET_REF(lwpnref)))
4942 {
4943 ret = s->drownclk * 10000;
4944 }
4945 break;
4946
4947 case LWPNDROWNCMB:
4948 if(auto s=checkLWpn(GET_REF(lwpnref)))
4949 {
4950 ret = s->drownCombo * 10000;
4951 }
4952 break;
4953
4954 case LWPNFAKEZ:
4955 if(auto s=checkLWpn(GET_REF(lwpnref)))
4956 {
4957 if ( get_qr(qr_SPRITEXY_IS_FLOAT) )
4958 {
4959 ret=(s->fakez).getZLong();
4960 }
4961 else
4962 ret=((int32_t)s->fakez)*10000;
4963 }
4964 break;
4965
4966 case LWPNGLOWRAD:
4967
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48553 times.
48553 if(auto s=checkLWpn(GET_REF(lwpnref)))
4968 {
4969 48553 ret = s->glowRad * 10000;
4970 48553 }
4971 48553 break;
4972
4973 case LWPNGLOWSHP:
4974 if(auto s=checkLWpn(GET_REF(lwpnref)))
4975 {
4976 ret = s->glowShape * 10000;
4977 }
4978 break;
4979
4980 case LWPNUNBL:
4981 if(auto s=checkLWpn(GET_REF(lwpnref)))
4982 {
4983 ret = s->unblockable * 10000;
4984 }
4985 break;
4986
4987 case LWPNSHADOWSPR:
4988 if(auto s=checkLWpn(GET_REF(lwpnref)))
4989 {
4990 ret = s->spr_shadow * 10000;
4991 }
4992 break;
4993 case LWSWHOOKED:
4994 if(auto s=checkLWpn(GET_REF(lwpnref)))
4995 {
4996 ret = s->switch_hooked ? 10000 : 0;
4997 }
4998 break;
4999 case LWPNTIMEOUT:
5000 if(auto s=checkLWpn(GET_REF(lwpnref)))
5001 {
5002 ret = s->weap_timeout * 10000;
5003 }
5004 break;
5005 case LWPNDEATHITEM:
5006 if(auto s=checkLWpn(GET_REF(lwpnref)))
5007 {
5008 ret = s->death_spawnitem * 10000;
5009 }
5010 break;
5011 case LWPNDEATHDROPSET:
5012 if(auto s=checkLWpn(GET_REF(lwpnref)))
5013 {
5014 ret = s->death_spawndropset * 10000;
5015 }
5016 break;
5017 case LWPNDEATHIPICKUP:
5018 if(auto s=checkLWpn(GET_REF(lwpnref)))
5019 {
5020 ret = s->death_item_pflags * 10000;
5021 }
5022 break;
5023 case LWPNDEATHSPRITE:
5024 if(auto s=checkLWpn(GET_REF(lwpnref)))
5025 {
5026 ret = s->death_sprite * 10000;
5027 }
5028 break;
5029 case LWPNDEATHSFX:
5030 if(auto s=checkLWpn(GET_REF(lwpnref)))
5031 {
5032 ret = s->death_sfx * 10000;
5033 }
5034 break;
5035 case LWPNLIFTLEVEL:
5036 if(auto s=checkLWpn(GET_REF(lwpnref)))
5037 {
5038 ret = s->lift_level * 10000;
5039 }
5040 break;
5041 case LWPNLIFTTIME:
5042 if(auto s=checkLWpn(GET_REF(lwpnref)))
5043 {
5044 ret = s->lift_time * 10000;
5045 }
5046 break;
5047 case LWPNLIFTHEIGHT:
5048 if(auto s=checkLWpn(GET_REF(lwpnref)))
5049 {
5050 ret = s->lift_height.getZLong();
5051 }
5052 break;
5053
5054 ///----------------------------------------------------------------------------------------------------//
5055 //EWeapon Variables
5056 case EWPNSCALE:
5057 if ( get_qr(qr_OLDSPRITEDRAWS) )
5058 {
5059 scripting_log_error_with_context("To use this you must disable the quest rule 'Old (Faster) Sprite Drawing'.");
5060 ret = -1; break;
5061 }
5062 if(auto s=checkEWpn(GET_REF(ewpnref)))
5063 ret=((int32_t)s->scale)*100.0;
5064
5065 break;
5066
5067 case EWPNX:
5068
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4354592 times.
4354592 if(auto s=checkEWpn(GET_REF(ewpnref)))
5069 {
5070
2/2
✓ Branch 0 taken 219464 times.
✓ Branch 1 taken 4135128 times.
4354592 if ( get_qr(qr_SPRITEXY_IS_FLOAT) )
5071 {
5072 219464 ret=(s->x).getZLong();
5073 219464 }
5074 else
5075 4135128 ret=((int32_t)s->x)*10000;
5076 4354592 }
5077 4354592 break;
5078
5079 case SPRITEMAXEWPN:
5080 {
5081 //No bounds check, as this is a universal function and works from NULL pointers!
5082 ret = Ewpns.getMax() * 10000;
5083 break;
5084 }
5085
5086 case EWPNY:
5087
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4354690 times.
4354690 if(auto s=checkEWpn(GET_REF(ewpnref)))
5088 {
5089
2/2
✓ Branch 0 taken 219317 times.
✓ Branch 1 taken 4135373 times.
4354690 if ( get_qr(qr_SPRITEXY_IS_FLOAT) )
5090 {
5091 219317 ret=(s->y).getZLong();
5092 219317 }
5093 else
5094 4135373 ret=((int32_t)s->y)*10000;
5095 4354690 }
5096 4354690 break;
5097
5098 case EWPNZ:
5099
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 552907 times.
552907 if(auto s=checkEWpn(GET_REF(ewpnref)))
5100 {
5101
2/2
✓ Branch 0 taken 1432 times.
✓ Branch 1 taken 551475 times.
552907 if ( get_qr(qr_SPRITEXY_IS_FLOAT) )
5102 {
5103 1432 ret=(s->z).getZLong();
5104 1432 }
5105 else
5106 551475 ret=((int32_t)s->z)*10000;
5107 552907 }
5108 552907 break;
5109
5110 case EWPNJUMP:
5111 if(auto s=checkEWpn(GET_REF(ewpnref)))
5112 {
5113 ret = s->fall.getZLong() / -100;
5114 if (get_qr(qr_SPRITE_JUMP_IS_TRUNCATED)) ret = trunc(ret / 10000) * 10000;
5115 }
5116
5117 break;
5118
5119 case EWPNFAKEJUMP:
5120 if(auto s=checkEWpn(GET_REF(ewpnref)))
5121 {
5122 ret = s->fakefall.getZLong() / -100;
5123 if (get_qr(qr_SPRITE_JUMP_IS_TRUNCATED)) ret = trunc(ret / 10000) * 10000;
5124 }
5125
5126 break;
5127
5128 case EWPNDIR:
5129
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61563 times.
61563 if(auto s=checkEWpn(GET_REF(ewpnref)))
5130 61563 ret=s->dir*10000;
5131
5132 61563 break;
5133
5134 case EWPNLEVEL:
5135
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2845 times.
2845 if(auto s=checkEWpn(GET_REF(ewpnref)))
5136 2845 ret=s->level*10000;
5137
5138 2845 break;
5139
5140 case EWPNGRAVITY:
5141 if(auto s=checkEWpn(GET_REF(ewpnref)))
5142 ret=((s->moveflags & move_obeys_grav) ? 10000 : 0);
5143
5144 break;
5145
5146 case EWPNSTEP:
5147
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 647006 times.
647006 if(auto s=checkEWpn(GET_REF(ewpnref)))
5148 {
5149
3/4
✓ Branch 0 taken 610183 times.
✓ Branch 1 taken 36823 times.
✓ Branch 2 taken 610183 times.
✗ Branch 3 not taken.
647006 if ( get_qr(qr_STEP_IS_FLOAT) || replay_is_active() )
5150 {
5151 647006 ret=s->step.getZLong() * 100;
5152 647006 }
5153 //old, buggy code replication, round two: Go! -Z
5154 //else ret = ( ( ( s->step ) * 100.0 ).getZLong() );
5155 //old, buggy code replication, round FOUR: Go! -Z
5156 else ret = (int32_t)((float)s->step * 1000000.0);
5157 647006 }
5158 //else
5159 //{
5160 //old, buggy code replication, round THREE: Go! -Z
5161 // double tmp = ( s->step.getFloat() ) * 1000000.0;
5162 // ret = int32_t(tmp);
5163 //}
5164 647006 break;
5165
5166 case EWPNANGLE:
5167
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 908111 times.
908111 if(auto s=checkEWpn(GET_REF(ewpnref)))
5168 908111 ret=(int32_t)(s->angle*10000);
5169
5170 908111 break;
5171
5172 case EWPNDEGANGLE:
5173
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3341 times.
3341 if(auto s=checkEWpn(GET_REF(ewpnref)))
5174 {
5175 3341 ret=(int32_t)(s->angle*(180.0 / PI)*10000);
5176 3341 }
5177
5178 3341 break;
5179
5180 case EWPNVX:
5181 if(auto s=checkEWpn(GET_REF(ewpnref)))
5182 {
5183 if (s->angular)
5184 ret = int32_t(zc::math::Cos(s->angle)*10000.0*s->step);
5185 else
5186 {
5187 switch(NORMAL_DIR(s->dir))
5188 {
5189 case l_up:
5190 case l_down:
5191 case left:
5192 ret = int32_t(-10000.0*s->step);
5193 break;
5194 case r_up:
5195 case r_down:
5196 case right:
5197 ret = int32_t(10000.0*s->step);
5198 break;
5199
5200 default:
5201 ret = 0;
5202 break;
5203 }
5204 }
5205 }
5206
5207 break;
5208
5209 case EWPNVY:
5210 if(auto s=checkEWpn(GET_REF(ewpnref)))
5211 {
5212 if (s->angular)
5213 ret = int32_t(zc::math::Sin(s->angle)*10000.0*s->step);
5214 else
5215 {
5216 switch(NORMAL_DIR(s->dir))
5217 {
5218 case l_up:
5219 case r_up:
5220 case up:
5221 ret = int32_t(-10000.0*s->step);
5222 break;
5223 case l_down:
5224 case r_down:
5225 case down:
5226 ret = int32_t(10000.0*s->step);
5227 break;
5228
5229 default:
5230 ret = 0;
5231 break;
5232 }
5233 }
5234 }
5235
5236 break;
5237
5238
5239 case EWPNANGULAR:
5240
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 170980 times.
170980 if(auto s=checkEWpn(GET_REF(ewpnref)))
5241 170980 ret=s->angular*10000;
5242
5243 170980 break;
5244
5245 case EWPNAUTOROTATE:
5246 if(auto s=checkEWpn(GET_REF(ewpnref)))
5247 ret=s->autorotate*10000;
5248
5249 break;
5250
5251 case EWPNBEHIND:
5252 if(auto s=checkEWpn(GET_REF(ewpnref)))
5253 ret=s->behind*10000;
5254
5255 break;
5256
5257 case EWPNDRAWTYPE:
5258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46359 times.
46359 if(auto s=checkEWpn(GET_REF(ewpnref)))
5259 46359 ret=s->drawstyle*10000;
5260
5261 46359 break;
5262
5263 case EWPNPOWER:
5264
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 99454 times.
99454 if(auto s=checkEWpn(GET_REF(ewpnref)))
5265 99454 ret=s->power*10000;
5266
5267 99454 break;
5268
5269 case EWPNDEAD:
5270
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6052 times.
6052 if(auto s=checkEWpn(GET_REF(ewpnref)))
5271 6052 ret=s->dead*10000;
5272
5273 6052 break;
5274
5275 case EWPNTYPE:
5276
2/2
✓ Branch 0 taken 72689 times.
✓ Branch 1 taken 2900624 times.
2973313 if(auto s=checkEWpn(GET_REF(ewpnref)))
5277 2900624 ret=s->id*10000;
5278
5279 2973313 break;
5280
5281 case EWPNTILE:
5282
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 205116 times.
205116 if(auto s=checkEWpn(GET_REF(ewpnref)))
5283 205116 ret=s->tile*10000;
5284
5285 205116 break;
5286
5287 case EWPNSCRIPTTILE:
5288 if(auto s=checkEWpn(GET_REF(ewpnref)))
5289 ret=s->scripttile*10000;
5290
5291 break;
5292
5293 case EWPNSCRIPTFLIP:
5294 if(auto s=checkEWpn(GET_REF(ewpnref)))
5295 ret=s->scriptflip*10000;
5296
5297 break;
5298
5299 case EWPNCSET:
5300
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65418 times.
65418 if(auto s=checkEWpn(GET_REF(ewpnref)))
5301 65418 ret=s->cs*10000;
5302
5303 65418 break;
5304
5305 case EWPNFLASHCSET:
5306 if(auto s=checkEWpn(GET_REF(ewpnref)))
5307 ret=(s->o_cset>>4)*10000;
5308
5309 break;
5310
5311 case EWPNFRAMES:
5312
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32642 times.
32642 if(auto s=checkEWpn(GET_REF(ewpnref)))
5313 32642 ret=s->frames*10000;
5314
5315 32642 break;
5316
5317 case EWPNFRAME:
5318 if(auto s=checkEWpn(GET_REF(ewpnref)))
5319 ret=s->aframe*10000;
5320
5321 break;
5322
5323 case EWPNASPEED:
5324
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32642 times.
32642 if(auto s=checkEWpn(GET_REF(ewpnref)))
5325 32642 ret=s->o_speed*10000;
5326
5327 32642 break;
5328
5329 case EWPNFLASH:
5330 if(auto s=checkEWpn(GET_REF(ewpnref)))
5331 ret=s->flash*10000;
5332
5333 break;
5334
5335 case EWPNFLIP:
5336
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12006 times.
12006 if(auto s=checkEWpn(GET_REF(ewpnref)))
5337 12006 ret=s->flip*10000;
5338
5339 12006 break;
5340
5341 case EWPNROTATION:
5342
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 218 times.
218 if ( get_qr(qr_OLDSPRITEDRAWS) )
5343 {
5344 scripting_log_error_with_context("To use this you must disable the quest rule 'Old (Faster) Sprite Drawing'");
5345 break;
5346 }
5347
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 218 times.
218 if(auto s=checkEWpn(GET_REF(ewpnref)))
5348 218 ret=s->rotation*10000;
5349
5350 218 break;
5351
5352 case EWPNCOUNT:
5353 6662300 ret=Ewpns.Count()*10000;
5354 6662300 break;
5355
5356 case EWPNEXTEND:
5357 if(auto s=checkEWpn(GET_REF(ewpnref)))
5358 ret=s->extend*10000;
5359
5360 break;
5361
5362 case EWPNOTILE:
5363
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10635 times.
10635 if(auto s=checkEWpn(GET_REF(ewpnref)))
5364 10635 ret=s->o_tile*10000;
5365
5366 10635 break;
5367
5368 case EWPNOCSET:
5369 if(auto s=checkEWpn(GET_REF(ewpnref)))
5370 ret=(s->o_cset&15)*10000;
5371
5372 break;
5373
5374 case EWPNHXOFS:
5375
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 157773 times.
157773 if(auto s=checkEWpn(GET_REF(ewpnref)))
5376 157773 ret=(s->hxofs)*10000;
5377
5378 157773 break;
5379
5380 case EWPNHYOFS:
5381
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 157773 times.
157773 if(auto s=checkEWpn(GET_REF(ewpnref)))
5382 157773 ret=(s->hyofs)*10000;
5383
5384 157773 break;
5385
5386 case EWPNXOFS:
5387
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48464 times.
48464 if(auto s=checkEWpn(GET_REF(ewpnref)))
5388 48464 ret=((int32_t)(s->xofs))*10000;
5389
5390 48464 break;
5391
5392 case EWPNYOFS:
5393
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60558 times.
60558 if(auto s=checkEWpn(GET_REF(ewpnref)))
5394
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60558 times.
60558 ret=((int32_t)(s->yofs-(get_qr(qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset)))*10000;
5395
5396 60558 break;
5397
5398 case EWPNSHADOWXOFS:
5399 if(auto s=checkEWpn(GET_REF(ewpnref)))
5400 ret=((int32_t)(s->shadowxofs))*10000;
5401
5402 break;
5403
5404 case EWPNSHADOWYOFS:
5405 if(auto s=checkEWpn(GET_REF(ewpnref)))
5406 ret=((int32_t)(s->shadowyofs))*10000;
5407
5408 break;
5409 case EWPNTOTALDYOFFS:
5410 if(auto s=checkEWpn(GET_REF(ewpnref)))
5411 ret = ((int32_t)(s->yofs-(get_qr(qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset))
5412 + ((s->switch_hooked && Hero.switchhookstyle == swRISE)
5413 ? -(8-(abs(Hero.switchhookclk-32)/4)) : 0) * 10000);
5414 break;
5415
5416 case EWPNZOFS:
5417
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1880 times.
1880 if(auto s=checkEWpn(GET_REF(ewpnref)))
5418 1880 ret=((int32_t)(s->zofs))*10000;
5419
5420 1880 break;
5421
5422 case EWPNHXSZ:
5423
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 149564 times.
149564 if(auto s=checkEWpn(GET_REF(ewpnref)))
5424 149564 ret=(s->hit_width)*10000;
5425
5426 149564 break;
5427
5428 case EWPNHYSZ:
5429
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 149564 times.
149564 if(auto s=checkEWpn(GET_REF(ewpnref)))
5430 149564 ret=(s->hit_height)*10000;
5431
5432 149564 break;
5433
5434 case EWPNHZSZ:
5435
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 81355 times.
81355 if(auto s=checkEWpn(GET_REF(ewpnref)))
5436 81355 ret=(s->hzsz)*10000;
5437
5438 81355 break;
5439
5440 case EWPNTXSZ:
5441
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 125257 times.
125257 if(auto s=checkEWpn(GET_REF(ewpnref)))
5442 125257 ret=(s->txsz)*10000;
5443
5444 125257 break;
5445
5446 case EWPNTYSZ:
5447
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 125257 times.
125257 if(auto s=checkEWpn(GET_REF(ewpnref)))
5448 125257 ret=(s->tysz)*10000;
5449
5450 125257 break;
5451
5452 case EWPNCOLLDET:
5453
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13583 times.
13583 if(auto s=checkEWpn(GET_REF(ewpnref)))
5454 13583 ret=(s->scriptcoldet)*10000;
5455
5456 13583 break;
5457
5458 case EWPNENGINEANIMATE:
5459 if(auto s=checkEWpn(GET_REF(ewpnref)))
5460 ret=(s->do_animation)*10000;
5461
5462 break;
5463
5464 case EWPNPARENT:
5465 if(auto s=checkEWpn(GET_REF(ewpnref)))
5466 ret= ((get_qr(qr_OLDEWPNPARENT)) ? (s->parentid)*10000 : (s->parentid));
5467
5468 break;
5469
5470 case EWEAPONSCRIPTUID:
5471 if(auto s=checkEWpn(GET_REF(ewpnref)))
5472 ret=(s->getUID());
5473
5474 break;
5475
5476 case EWPNPARENTUID:
5477 if(auto s=checkEWpn(GET_REF(ewpnref)))
5478 ret = s->parent ? s->parent->getUID() : 0;
5479
5480 break;
5481
5482 case EWPNSCRIPT:
5483
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7570 times.
7570 if(auto s=checkEWpn(GET_REF(ewpnref)))
5484 7570 ret=(s->script)*10000;
5485
5486 7570 break;
5487
5488 case EWPNFALLCLK:
5489 if(auto s=checkEWpn(GET_REF(ewpnref)))
5490 {
5491 ret = s->fallclk * 10000;
5492 }
5493 break;
5494
5495 case EWPNFALLCMB:
5496 if(auto s=checkEWpn(GET_REF(ewpnref)))
5497 {
5498 ret = s->fallCombo * 10000;
5499 }
5500 break;
5501
5502 case EWPNDROWNCLK:
5503 if(auto s=checkEWpn(GET_REF(ewpnref)))
5504 {
5505 ret = s->drownclk * 10000;
5506 }
5507 break;
5508
5509 case EWPNDROWNCMB:
5510 if(auto s=checkEWpn(GET_REF(ewpnref)))
5511 {
5512 ret = s->drownCombo * 10000;
5513 }
5514 break;
5515 case EWPNFAKEZ:
5516 if(auto s=checkEWpn(GET_REF(ewpnref)))
5517 {
5518 if ( get_qr(qr_SPRITEXY_IS_FLOAT) )
5519 {
5520 ret=(s->fakez).getZLong();
5521 }
5522 else
5523 ret=((int32_t)s->fakez)*10000;
5524 }
5525 break;
5526
5527 case EWPNGLOWRAD:
5528
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30735 times.
30735 if(auto s=checkEWpn(GET_REF(ewpnref)))
5529 {
5530 30735 ret = s->glowRad * 10000;
5531 30735 }
5532 30735 break;
5533
5534 case EWPNGLOWSHP:
5535 if(auto s=checkEWpn(GET_REF(ewpnref)))
5536 {
5537 ret = s->glowShape * 10000;
5538 }
5539 break;
5540
5541 case EWPNUNBL:
5542 if(auto s=checkEWpn(GET_REF(ewpnref)))
5543 {
5544 ret = s->unblockable * 10000;
5545 }
5546 break;
5547
5548 case EWPNSHADOWSPR:
5549 if(auto s=checkEWpn(GET_REF(ewpnref)))
5550 {
5551 ret = s->spr_shadow * 10000;
5552 }
5553 break;
5554 case EWSWHOOKED:
5555 if(auto s=checkEWpn(GET_REF(ewpnref)))
5556 {
5557 ret = s->switch_hooked ? 10000 : 0;
5558 }
5559 break;
5560 case EWPNTIMEOUT:
5561 if(auto s=checkEWpn(GET_REF(ewpnref)))
5562 {
5563 ret = s->weap_timeout * 10000;
5564 }
5565 break;
5566 case EWPNDEATHITEM:
5567 if(auto s=checkEWpn(GET_REF(ewpnref)))
5568 {
5569 ret = s->death_spawnitem * 10000;
5570 }
5571 break;
5572 case EWPNDEATHDROPSET:
5573 if(auto s=checkEWpn(GET_REF(ewpnref)))
5574 {
5575 ret = s->death_spawndropset * 10000;
5576 }
5577 break;
5578 case EWPNDEATHIPICKUP:
5579 if(auto s=checkEWpn(GET_REF(ewpnref)))
5580 {
5581 ret = s->death_item_pflags * 10000;
5582 }
5583 break;
5584 case EWPNDEATHSPRITE:
5585 if(auto s=checkEWpn(GET_REF(ewpnref)))
5586 {
5587 ret = s->death_sprite * 10000;
5588 }
5589 break;
5590 case EWPNDEATHSFX:
5591 if(auto s=checkEWpn(GET_REF(ewpnref)))
5592 {
5593 ret = s->death_sfx * 10000;
5594 }
5595 break;
5596 case EWPNLIFTLEVEL:
5597 if(auto s=checkEWpn(GET_REF(ewpnref)))
5598 {
5599 ret = s->lift_level * 10000;
5600 }
5601 break;
5602 case EWPNLIFTTIME:
5603 if(auto s=checkEWpn(GET_REF(ewpnref)))
5604 {
5605 ret = s->lift_time * 10000;
5606 }
5607 break;
5608 case EWPNLIFTHEIGHT:
5609 if(auto s=checkEWpn(GET_REF(ewpnref)))
5610 {
5611 ret = s->lift_height.getZLong();
5612 }
5613 break;
5614
5615 case SCREENSCRDATASIZE:
5616 {
5617 int index = map_screen_index(cur_map, ri->screenref);
5618 if (index < 0) break;
5619 ret = 10000*game->scriptDataSize(index);
5620 break;
5621 }
5622
5623 case DISTANCE:
5624 {
5625 823233 double x1 = double(GET_D(rSFTEMP) / 10000.0);
5626 823233 double y1 = double(GET_D(rINDEX) / 10000.0);
5627 823233 double x2 = double(GET_D(rINDEX2) / 10000.0);
5628 823233 double y2 = double(GET_D(rEXP1) / 10000.0);
5629
5630
5631
5632 823233 int32_t result = FFCore.Distance(x1, y1, x2, y2);
5633 823233 ret = (result);
5634
5635 823233 break;
5636 }
5637 case LONGDISTANCE:
5638 {
5639 double x1 = double(GET_D(rSFTEMP));
5640 double y1 = double(GET_D(rINDEX));
5641 double x2 = double(GET_D(rINDEX2));
5642 double y2 = double(GET_D(rEXP1));
5643
5644
5645
5646 int32_t result = FFCore.LongDistance(x1, y1, x2, y2);
5647 ret = (result);
5648
5649 break;
5650 }
5651
5652 case DISTANCESCALE:
5653 {
5654 double x1 = (double)(GET_D(rSFTEMP) / 10000.0);
5655 double y1 = (double)(GET_D(rINDEX) / 10000.0);
5656 double x2 = (double)(GET_D(rINDEX2) / 10000.0);
5657 double y2 = (double)(GET_D(rEXP1) / 10000.0);
5658
5659 int32_t scale = (GET_D(rWHAT_NO_7)/10000);
5660
5661 if ( !scale ) scale = 10000;
5662 int32_t result = FFCore.Distance(x1, y1, x2, y2, scale);
5663 ret = (result);
5664
5665 break;
5666 }
5667 case LONGDISTANCESCALE:
5668 {
5669 double x1 = (double)(GET_D(rSFTEMP));
5670 double y1 = (double)(GET_D(rINDEX));
5671 double x2 = (double)(GET_D(rINDEX2));
5672 double y2 = (double)(GET_D(rEXP1));
5673
5674 int32_t scale = (GET_D(rWHAT_NO_7));
5675
5676 if ( !scale ) scale = 1;
5677 int32_t result = FFCore.LongDistance(x1, y1, x2, y2, scale);
5678 ret = (result);
5679
5680 break;
5681 }
5682
5683 case ALLOCATEBITMAPR:
5684 450 ret=FFCore.get_free_bitmap();
5685 450 break;
5686
5687 case GETMIDI:
5688 107342 ret=(currmidi-MIDIOFFSET_ZSCRIPT)*10000;
5689 107342 break;
5690
5691 case CURDSCR:
5692 {
5693 12771624 int32_t di = (get_currscr()-DMaps[get_currdmap()].xoff);
5694
2/2
✓ Branch 0 taken 5180916 times.
✓ Branch 1 taken 7590708 times.
12771624 ret=(DMaps[get_currdmap()].type==dmOVERW ? cur_screen : di)*10000;
5695 }
5696 12771624 break;
5697
5698 case GAMEMAXMAPS:
5699 96 ret = (map_count)*10000;
5700 96 break;
5701 case GAMENUMMESSAGES:
5702 ret = (msg_count-1) * 10000;
5703 break;
5704
5705 case CURDMAP:
5706 65088706 ret=cur_dmap*10000;
5707 65088706 break;
5708
5709 case CURLEVEL:
5710 16014487 ret=DMaps[get_currdmap()].level*10000;
5711 16014487 break;
5712
5713 case GAMECLICKFREEZE:
5714 ret=disableClickToFreeze?0:10000;
5715 break;
5716
5717
5718 case NOACTIVESUBSC:
5719 ret=Hero.stopSubscreenFalling()?10000:0;
5720 break;///----------------------------------------------------------------------------------------------------//
5721 //BottleTypes
5722
5723 case BOTTLENEXT:
5724 {
5725 if(bottletype* ptr = checkBottleData(GET_REF(bottletyperef)))
5726 {
5727 ret = 10000L * ptr->next_type;
5728 }
5729 else ret = -10000L;
5730 }
5731 break;
5732
5733 ///----------------------------------------------------------------------------------------------------//
5734 //Region
5735
5736 case REGION_WIDTH:
5737 {
5738 390647 ret = world_w * 10000;
5739 }
5740 390647 break;
5741
5742 case REGION_HEIGHT:
5743 {
5744 382914 ret = world_h * 10000;
5745 }
5746 382914 break;
5747
5748 case REGION_SCREEN_WIDTH:
5749 {
5750 2662 ret = cur_region.screen_width * 10000;
5751 }
5752 2662 break;
5753
5754 case REGION_SCREEN_HEIGHT:
5755 {
5756 2599 ret = cur_region.screen_height * 10000;
5757 }
5758 2599 break;
5759
5760 case REGION_NUM_COMBOS:
5761 {
5762 11700413 ret = region_num_rpos * 10000;
5763 }
5764 11700413 break;
5765
5766 case REGION_ID:
5767 {
5768 27276802 ret = get_current_region_id() * 10000;
5769 }
5770 27276802 break;
5771
5772 case REGION_ORIGIN_SCREEN:
5773 {
5774 ret = cur_screen;
5775 }
5776 break;
5777
5778 ///----------------------------------------------------------------------------------------------------//
5779 //Viewport
5780
5781 case VIEWPORT_TARGET:
5782 {
5783 ret = get_viewport_sprite()->uid;
5784 }
5785 break;
5786
5787 case VIEWPORT_MODE:
5788 {
5789 ret = (int)viewport_mode;
5790 }
5791 break;
5792
5793 case VIEWPORT_X:
5794 {
5795 24940 ret = viewport.x * 10000;
5796 }
5797 24940 break;
5798
5799 case VIEWPORT_Y:
5800 {
5801 21112 ret = viewport.y * 10000;
5802 }
5803 21112 break;
5804
5805 case VIEWPORT_WIDTH:
5806 {
5807 8014 ret = viewport.w * 10000;
5808 }
5809 8014 break;
5810
5811 case VIEWPORT_HEIGHT:
5812 {
5813 11842 ret = viewport.h * 10000;
5814 }
5815 11842 break;
5816
5817 ///----------------------------------------------------------------------------------------------------//
5818 //Screen Information
5819
5820 #define GET_SCREENDATA_VAR_INT32(member) \
5821 { \
5822 ret = (get_scr(GET_REF(screenref))->member *10000); \
5823 } \
5824
5825 #define GET_SCREENDATA_VAR_INT16(member) \
5826 { \
5827 ret = (get_scr(GET_REF(screenref))->member *10000); \
5828 } \
5829
5830 #define GET_SCREENDATA_VAR_BYTE(member) \
5831 { \
5832 ret = (get_scr(GET_REF(screenref))->member *10000); \
5833 } \
5834
5835 #define GET_SCREENDATA_BYTE_INDEX(member, indexbound) \
5836 { \
5837 int32_t indx = GET_D(rINDEX) / 10000; \
5838 ret = (get_scr(GET_REF(screenref))->member[indx] *10000); \
5839 } \
5840
5841 //byte
5842 #define GET_SCREENDATA_LAYER_INDEX(member, indexbound) \
5843 { \
5844 int32_t indx = GET_D(rINDEX) / 10000; \
5845 if (BC::checkIndex(indx, 1, indexbound) != SH::_NoError) \
5846 { \
5847 ret = -10000; \
5848 } \
5849 else \
5850 { \
5851 ret = (get_scr(GET_REF(screenref))->member[indx-1] *10000); \
5852 } \
5853 } \
5854
5855 #define GET_SCREENDATA_BOOL_INDEX(member, indexbound) \
5856 { \
5857 int32_t indx = GET_D(rINDEX) / 10000; \
5858 if (BC::checkIndex(indx, 0, indexbound) != SH::_NoError) \
5859 { \
5860 ret = -10000; \
5861 } \
5862 else \
5863 { \
5864 ret = (get_scr(GET_REF(screenref))->member[indx]?10000:0); \
5865 } \
5866 } \
5867
5868
5869 #define GET_SCREENDATA_FLAG(member, str, indexbound) \
5870 { \
5871 int32_t flag = (value/10000); \
5872 ret = (get_scr(GET_REF(screenref))->member&flag) ? 10000 : 0); \
5873 } \
5874
5875 case SCREENDATAVALID: GET_SCREENDATA_VAR_BYTE(valid); break; //b
5876 case SCREENDATAGUY: GET_SCREENDATA_VAR_BYTE(guy); break; //b
5877 case SCREENDATASTRING: GET_SCREENDATA_VAR_INT32(str); break; //w
5878 case SCREENDATAROOM: GET_SCREENDATA_VAR_BYTE(room); break; //b
5879 case SCREENDATAITEM:
5880 {
5881 mapscr* scr = get_scr(GET_REF(screenref));
5882 if(scr->hasitem)
5883 ret = (scr->item *10000);
5884 else ret = -10000;
5885 break;
5886 }
5887 case SCREENDATAHASITEM: GET_SCREENDATA_VAR_BYTE(hasitem); break; //b
5888 case SCREENDATADOORCOMBOSET: GET_SCREENDATA_VAR_INT32(door_combo_set); break; //w
5889 case SCREENDATAWARPRETURNC: GET_SCREENDATA_VAR_INT32(warpreturnc); break; //w
5890 case SCREENDATASTAIRX: GET_SCREENDATA_VAR_BYTE(stairx); break; //b
5891 case SCREENDATASTAIRY: GET_SCREENDATA_VAR_BYTE(stairy); break; //b
5892 case SCREENDATAITEMX: GET_SCREENDATA_VAR_BYTE(itemx); break; //itemx
5893 case SCREENDATAITEMY: GET_SCREENDATA_VAR_BYTE(itemy); break; //itemy
5894 170974 case SCREENDATACOLOUR: GET_SCREENDATA_VAR_INT32(color); break; //w
5895 case SCREENDATAENEMYFLAGS: GET_SCREENDATA_VAR_BYTE(flags11); break; //b
5896 // Note: never used?
5897 case SCREENDATADOOR: GET_SCREENDATA_BYTE_INDEX(door, 3); break; //b, 4 of these
5898 case SCREENDATAEXITDIR: GET_SCREENDATA_VAR_BYTE(exitdir); break; //b
5899 case SCREENDATAPATTERN: GET_SCREENDATA_VAR_BYTE(pattern); break; //b
5900 case SCREENDATAWARPARRIVALX: GET_SCREENDATA_VAR_BYTE(warparrivalx); break; //b
5901 case SCREENDATAWARPARRIVALY: GET_SCREENDATA_VAR_BYTE(warparrivaly); break; //b
5902 case SCREENDATASIDEWARPINDEX: GET_SCREENDATA_VAR_BYTE(sidewarpindex); break; //b
5903 case SCREENDATACATCHALL: GET_SCREENDATA_VAR_INT32(catchall); break; //W
5904
5905 case SCREENDATACSENSITIVE: GET_SCREENDATA_VAR_BYTE(csensitive); break; //B
5906 case SCREENDATANORESET: GET_SCREENDATA_VAR_INT32(noreset); break; //W
5907 case SCREENDATANOCARRY: GET_SCREENDATA_VAR_INT32(nocarry); break; //W
5908 case SCREENDATATIMEDWARPTICS: GET_SCREENDATA_VAR_INT32(timedwarptics); break; //W
5909 case SCREENDATANEXTMAP: GET_SCREENDATA_VAR_BYTE(nextmap); break; //B
5910 case SCREENDATANEXTSCREEN: GET_SCREENDATA_VAR_BYTE(nextscr); break; //B
5911 case SCREENDATAVIEWX: break;//GET_SCREENDATA_VAR_INT32(viewX, "ViewX"); break; //W
5912 case SCREENDATAVIEWY: break;//GET_SCREENDATA_VAR_INT32(viewY, "ViewY"); break; //W
5913 case SCREENDATASCREENWIDTH: break;//GET_SCREENDATA_VAR_BYTE(scrWidth, "Width"); break; //B
5914 case SCREENDATASCREENHEIGHT: break;//GET_SCREENDATA_VAR_BYTE(scrHeight, "Height"); break; //B
5915 case SCREENDATAENTRYX: GET_SCREENDATA_VAR_BYTE(entry_x); break; //B
5916 case SCREENDATAENTRYY: GET_SCREENDATA_VAR_BYTE(entry_y); break; //B
5917 //Number of ffcs that are in use (have valid data
5918 // Note: that is totally not what its doing.
5919 case SCREENDATANUMFF:
5920 {
5921 int id = GET_D(rINDEX) / 10000;
5922 if (auto ffc = ResolveFFCWithID(id))
5923 ret = ffc->data != 0 ? 10000 : 0;
5924 break;
5925 }
5926
5927 // Note: never used?
5928 case SCREENDATAFFINITIALISED: {
5929 int32_t indx = GET_D(rINDEX) / 10000;
5930 if (indx < 0 || indx > MAX_FFCID)
5931 {
5932 scripting_log_error_with_context("Invalid index: %d", (indx));
5933 ret = -10000;
5934 }
5935 else
5936 {
5937 ret = get_script_engine_data(ScriptType::FFC, indx).initialized ? 10000 : 0;
5938 }
5939 }
5940 break;
5941
5942 case SCREENDATASCRIPTENTRY:
5943 {
5944 Z_scripterrlog("Unimplemented: %s\n", "ScriptEntry");
5945 ret = -10000;
5946 }
5947 break;
5948 case SCREENDATASCRIPTOCCUPANCY:
5949 {
5950 Z_scripterrlog("Unimplemented: %s\n", "ScriptOccupancy");
5951 ret = -10000;
5952 }
5953 break;
5954 case SCREENDATASCRIPTEXIT:
5955 {
5956 Z_scripterrlog("Unimplemented: %s\n", "ExitScript");
5957 ret = -10000;
5958 }
5959 break;
5960
5961 case SCREENDATAOCEANSFX: GET_SCREENDATA_VAR_BYTE(oceansfx); break; //B
5962 case SCREENDATABOSSSFX: GET_SCREENDATA_VAR_BYTE(bosssfx); break; //B
5963 17 case SCREENDATASECRETSFX: GET_SCREENDATA_VAR_BYTE(secretsfx); break; //B
5964 case SCREENDATAHOLDUPSFX: GET_SCREENDATA_VAR_BYTE(holdupsfx); break; //B
5965 case SCREENDATASCREENMIDI:
5966 {
5967 ret = ((get_scr(GET_REF(screenref))->screen_midi+(MIDIOFFSET_MAPSCR-MIDIOFFSET_ZSCRIPT)) *10000);
5968 break;
5969 }
5970 case SCREENDATA_GRAVITY_STRENGTH:
5971 {
5972 ret = get_scr(GET_REF(screenref))->screen_gravity.getZLong();
5973 break;
5974 }
5975 case SCREENDATA_TERMINAL_VELOCITY:
5976 {
5977 ret = get_scr(GET_REF(screenref))->screen_terminal_v.getZLong();
5978 break;
5979 }
5980 case SCREENDATALENSLAYER: GET_SCREENDATA_VAR_BYTE(lens_layer); break; //B, OLD QUESTS ONLY?
5981
5982 case SCREENSECRETSTRIGGERED:
5983 {
5984 41995 ret = get_screen_state(GET_REF(screenref)).triggered_secrets ? 10000L : 0L;
5985 41995 break;
5986 }
5987
5988 case SCREENDATAGUYCOUNT:
5989 {
5990 int mi = mapind(cur_map, GET_REF(screenref));
5991 if(mi < 0)
5992 ret = -10000;
5993 else ret = game->guys[mi] * 10000;
5994 break;
5995 }
5996 case SCREENDATAEXDOOR:
5997 {
5998 ret = 0;
5999 int mi = mapind(cur_map, GET_REF(screenref));
6000 if(mi < 0) break;
6001 int dir = SH::read_stack(ri->sp+1) / 10000;
6002 int ind = SH::read_stack(ri->sp+0) / 10000;
6003 if(unsigned(dir) > 3)
6004 Z_scripterrlog("Invalid dir '%d' passed to 'Screen->GetExDoor()'; must be 0-3\n", dir);
6005 else if(unsigned(ind) > 7)
6006 Z_scripterrlog("Invalid index '%d' passed to 'Screen->GetExDoor()'; must be 0-7\n", ind);
6007 else
6008 {
6009 int bit = 1<<ind;
6010 ret = (game->xdoors[mi][dir]&bit) ? 10000 : 0;
6011 }
6012 break;
6013 }
6014
6015 case SHOWNMSG:
6016 {
6017
4/4
✓ Branch 0 taken 3052 times.
✓ Branch 1 taken 10916 times.
✓ Branch 2 taken 3000 times.
✓ Branch 3 taken 52 times.
13968 ret = ((msg_active || msg_onscreen) ? msgstr : 0) * 10000L;
6018 13968 break;
6019 }
6020
6021 case SDDD:
6022 43250 ret=FFScript::get_screen_d((GET_D(rINDEX))/10000 + ((get_currdmap())<<7), GET_D(rINDEX2) / 10000);
6023 43250 break;
6024
6025 case LINKOTILE:
6026 ret=FFCore.getHeroOTile(GET_D(rINDEX)/10000, GET_D(rINDEX2) / 10000);
6027 break;
6028
6029 case SDDDD:
6030 280 ret=FFScript::get_screen_d(GET_D(rINDEX2) / 10000 + ((GET_D(rINDEX)/10000)<<7), GET_D(rEXP1) / 10000);
6031 280 break;
6032
6033 case SCREENSCRIPT:
6034 ret=get_scr(GET_REF(screenref))->script*10000;
6035 break;
6036
6037 //These use the same method as GetScreenD -Z
6038 case SCREENWIDTH:
6039 // ret=FFScript::get_screenWidth(&TheMaps[(GET_D(rINDEX2) / 10000) * MAPSCRS + (GET_D(rINDEX)/10000)]);
6040 break;
6041
6042 case SCREENHEIGHT:
6043 // ret=FFScript::get_screenHeight(&TheMaps[(GET_D(rINDEX2) / 10000) * MAPSCRS + (GET_D(rINDEX)/10000)]);
6044 break;
6045
6046 case SCREENVIEWX:
6047 // ret=get_screenViewX(&TheMaps[(GET_D(rINDEX2) / 10000) * MAPSCRS + (GET_D(rINDEX)/10000)]);
6048 break;
6049
6050 case SCREENVIEWY:
6051 // ret=get_screenViewY(&TheMaps[(GET_D(rINDEX2) / 10000) * MAPSCRS + (GET_D(rINDEX)/10000)]);
6052 break;
6053
6054 case LIT:
6055 10246 ret= get_lights() ? 10000 : 0;
6056 10246 break;
6057
6058 case WAVY:
6059 7214 ret = wavy*10000;
6060 7214 break;
6061
6062 case QUAKE:
6063 2391 ret = quakeclk*10000;
6064 2391 break;
6065
6066 case NPCCOUNT:
6067 29999777 ret = guys.Count()*10000;
6068 29999777 break;
6069
6070 case ROOMDATA:
6071 47 ret = get_scr(GET_REF(screenref))->catchall*10000;
6072 47 break;
6073
6074 case ROOMTYPE:
6075 2 ret = get_scr(GET_REF(screenref))->room*10000;
6076 2 break;
6077
6078 case PUSHBLOCKX:
6079
2/2
✓ Branch 0 taken 38077 times.
✓ Branch 1 taken 710696 times.
748773 ret = mblock2.active() ? int32_t(mblock2.x)*10000 : -10000;
6080 748773 break;
6081
6082 case PUSHBLOCKY:
6083
2/2
✓ Branch 0 taken 14477 times.
✓ Branch 1 taken 98007 times.
112484 ret = mblock2.active() ? int32_t(mblock2.y)*10000 : -10000;
6084 112484 break;
6085
6086 case PUSHBLOCKLAYER:
6087 ret = mblock2.active() ? int32_t(mblock2.blockLayer)*10000 : -10000;
6088 break;
6089
6090 case PUSHBLOCKCOMBO:
6091 ret = mblock2.bcombo*10000;
6092 break;
6093
6094 case PUSHBLOCKCSET:
6095 ret = mblock2.cs*10000;
6096 break;
6097
6098 case UNDERCOMBO:
6099 1634 ret = get_scr(GET_REF(screenref))->undercombo*10000;
6100 1634 break;
6101
6102 case UNDERCSET:
6103 1608 ret = get_scr(GET_REF(screenref))->undercset*10000;
6104 1608 break;
6105
6106 case SCREEN_INDEX:
6107 32 ret = ri->screenref*10000;
6108 32 break;
6109
6110 case SCREEN_DRAW_ORIGIN:
6111 ret = (int)ri->screen_draw_origin;
6112 break;
6113
6114 case SCREEN_DRAW_ORIGIN_TARGET:
6115 ret = ri->screen_draw_origin_target;
6116 break;
6117
6118 //Creates an lweapon using an iemdata struct values to generate its properties.
6119 //Useful in conjunction with the new weapon editor.
6120 case CREATELWPNDX:
6121 {
6122 //Z_message("Trying to get Hero->SetExtend().\n");
6123 int32_t ID = (GET_D(rINDEX) / 10000);
6124 int32_t itemid = (GET_D(rINDEX2)/10000);
6125 itemid = vbound(itemid,0,(MAXITEMS-1));
6126
6127 // TODO: use has_space()
6128 if ( Lwpns.Count() < 256 )
6129 {
6130
6131 (void)Lwpns.add
6132 (
6133 new weapon
6134 (
6135 (zfix)0, /*X*/
6136 (zfix)0, /*Y*/
6137 (zfix)0, /*Z*/
6138 ID, /*id*/
6139 0, /*type*/
6140 0, /*power*/
6141 0, /*dir*/
6142 -1, /*Parentid*/
6143 Hero.getUID(), /*prntid*/
6144 false, /*isdummy*/
6145 1, /*script_gen*/
6146 1, /*islwpn*/
6147 (ID==wWind?1:0) /*special*/
6148 )
6149 );
6150 ri->lwpnref = Lwpns.spr(Lwpns.Count() - 1)->getUID();
6151
6152 weapon *w = (weapon*)Lwpns.spr(Lwpns.Count()-1); //last created
6153 //w->LOADGFX(FFCore.getDefWeaponSprite(ID)); //What the fuck Zoria, this broke old quests...
6154 w->ScriptGenerated = 1;
6155 w->isLWeapon = 1;
6156 if(ID == wWind) w->specialinfo = 1;
6157 //weapon *w = (weapon*)Lwpns.spr(Lwpns.Count()-1); //last created
6158 //w->LOADGFX(FFCore.getDefWeaponSprite(ID)); //not needed here because this has access to wpn->prent
6159 }
6160 else
6161 {
6162 Z_scripterrlog("Tried to create too many LWeapons on the screen. The current LWeapon count is: %d\n", Lwpns.Count());
6163 ri->lwpnref = 0;
6164 }
6165
6166 ret = ri->lwpnref;
6167 }
6168 break;
6169
6170 ///----------------------------------------------------------------------------------------------------//
6171 //New Datatype Variables
6172
6173 ///----------------------------------------------------------------------------------------------------//
6174 //spritedata sp-> Variables
6175
6176
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5603 times.
5603 case SPRITEDATATILE: GET_SPRITEDATA_VAR_INT(tile) break;
6177 case SPRITEDATAMISC: GET_SPRITEDATA_VAR_INT(misc) break;
6178 case SPRITEDATACSETS:
6179 {
6180
1/2
✓ Branch 0 taken 5603 times.
✗ Branch 1 not taken.
5603 if (auto sd = checkSpriteData(GET_REF(spritedataref)); !sd)
6181 ret = -10000;
6182 else
6183 5603 ret = ((sd->csets & 0xF) * 10000);
6184 5603 break;
6185 }
6186 case SPRITEDATAFLCSET:
6187 {
6188 if (auto sd = checkSpriteData(GET_REF(spritedataref)); !sd)
6189 ret = -10000;
6190 else
6191 ret = (((sd->csets & 0xF0)>>4) * 10000);
6192 break;
6193 }
6194
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5603 times.
5603 case SPRITEDATAFRAMES: GET_SPRITEDATA_VAR_INT(frames) break;
6195
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5603 times.
5603 case SPRITEDATASPEED: GET_SPRITEDATA_VAR_INT(speed) break;
6196 case SPRITEDATATYPE: GET_SPRITEDATA_VAR_INT(type) break;
6197 case SPRITEDATAID:
6198 {
6199 if(unsigned(GET_REF(spritedataref)) > (MAXWPNS-1) )
6200 {
6201 ret = -10000;
6202 Z_scripterrlog("Invalid Sprite ID passed to spritedata->ID: %d\n", GET_REF(spritedataref));
6203 break;
6204 }
6205 ret = ri->spritedataref*10000;
6206 break;
6207 }
6208
6209 ///----------------------------------------------------------------------------------------------------//
6210 //mapdata m-> variables
6211 #define GET_MAPDATA_VAR_INT32(member) \
6212 { \
6213 if ( mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)) ) \
6214 { \
6215 ret = (m->member *10000); \
6216 } \
6217 else \
6218 { \
6219 ret = -10000; \
6220 } \
6221 } \
6222
6223 #define GET_MAPDATA_VAR_INT16(member) \
6224 { \
6225 if ( mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)) ) \
6226 { \
6227 ret = (m->member *10000); \
6228 } \
6229 else \
6230 { \
6231 ret = -10000; \
6232 } \
6233 } \
6234
6235 #define GET_MAPDATA_VAR_BYTE(member) \
6236 { \
6237 if ( mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)) ) \
6238 { \
6239 ret = (m->member *10000); \
6240 } \
6241 else \
6242 { \
6243 ret = -10000; \
6244 } \
6245 } \
6246
6247 #define GET_MAPDATA_FLAG(member) \
6248 { \
6249 int32_t flag = (value/10000); \
6250 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref))) \
6251 { \
6252 ret = (m->member&flag) ? 10000 : 0); \
6253 } \
6254 else \
6255 { \
6256 ret = -10000; \
6257 } \
6258 } \
6259
6260 #define GET_MAPDATA_FFCPOS_INDEX32(member, indexbound) \
6261 { \
6262 int32_t index = (GET_D(rINDEX) / 10000); \
6263 if (auto handle = ResolveMapdataFFC(ri->mapdataref, index)) \
6264 { \
6265 ret = (handle.ffc->member).getZLong(); \
6266 } \
6267 else \
6268 { \
6269 ret = -10000; \
6270 } \
6271 } \
6272
6273 #define GET_MAPDATA_FFC_INDEX32(member, indexbound) \
6274 { \
6275 int32_t index = (GET_D(rINDEX) / 10000); \
6276 if (auto handle = ResolveMapdataFFC(ri->mapdataref, index)) \
6277 { \
6278 ret = (handle.ffc->member)*10000; \
6279 } \
6280 else \
6281 { \
6282 ret = -10000; \
6283 } \
6284 } \
6285
6286 #define GET_MAPDATA_FFC_INDEX32(member, indexbound) \
6287 { \
6288 int32_t index = (GET_D(rINDEX) / 10000); \
6289 if (auto handle = ResolveMapdataFFC(ri->mapdataref, index)) \
6290 { \
6291 ret = (handle.ffc->member)*10000; \
6292 } \
6293 else \
6294 { \
6295 ret = -10000; \
6296 } \
6297 } \
6298
6299 case LOADMAPDATA:
6300 7237302 ret=FFScript::loadMapData();
6301 7237302 break;
6302
6303 case CREATEBITMAP:
6304 {
6305 1509497 ret=FFCore.do_create_bitmap();
6306 1509497 break;
6307 }
6308
6309
1/2
✓ Branch 0 taken 51072 times.
✗ Branch 1 not taken.
51072 case MAPDATAVALID: GET_MAPDATA_VAR_BYTE(valid); break; //b
6310 case MAPDATAGUY: GET_MAPDATA_VAR_BYTE(guy); break; //b
6311 case MAPDATASTRING: GET_MAPDATA_VAR_INT32(str); break; //w
6312 case MAPDATAROOM: GET_MAPDATA_VAR_BYTE(room); break; //b
6313 case MAPDATAITEM:
6314 {
6315 if ( mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)) )
6316 {
6317 if(m->hasitem)
6318 ret = (m->item *10000);
6319 else ret = -10000;
6320 }
6321 else
6322 {
6323 ret = -10000;
6324 }
6325 break;
6326 }
6327 case MAPDATAREGIONID:
6328 {
6329 if (auto scr = ResolveMapdataScr(GET_REF(mapdataref)))
6330 ret = get_region_id(scr->map, scr->screen) * 10000;
6331 break;
6332 }
6333 case MAPDATAHASITEM: GET_MAPDATA_VAR_BYTE(hasitem); break; //b
6334 case MAPDATADOORCOMBOSET: GET_MAPDATA_VAR_INT32(door_combo_set); break; //w
6335 case MAPDATAWARPRETURNC: GET_MAPDATA_VAR_INT32(warpreturnc); break; //w
6336 case MAPDATASTAIRX: GET_MAPDATA_VAR_BYTE(stairx); break; //b
6337 case MAPDATASTAIRY: GET_MAPDATA_VAR_BYTE(stairy); break; //b
6338 case MAPDATAITEMX: GET_MAPDATA_VAR_BYTE(itemx); break; //itemx
6339 case MAPDATAITEMY: GET_MAPDATA_VAR_BYTE(itemy); break; //itemy
6340
1/2
✓ Branch 0 taken 51072 times.
✗ Branch 1 not taken.
51072 case MAPDATACOLOUR: GET_MAPDATA_VAR_INT32(color); break; //w
6341 case MAPDATAENEMYFLAGS: GET_MAPDATA_VAR_BYTE(flags11); break; //b
6342 case MAPDATAEXITDIR: GET_MAPDATA_VAR_BYTE(exitdir); break; //b
6343 case MAPDATAPATTERN: GET_MAPDATA_VAR_BYTE(pattern); break; //b
6344 case MAPDATAWARPARRIVALX: GET_MAPDATA_VAR_BYTE(warparrivalx); break; //b
6345 case MAPDATAWARPARRIVALY: GET_MAPDATA_VAR_BYTE(warparrivaly); break; //b
6346 case MAPDATASIDEWARPINDEX: GET_MAPDATA_VAR_BYTE(sidewarpindex); break; //b
6347 case MAPDATAUNDERCOMBO: GET_MAPDATA_VAR_INT32(undercombo); break; //w
6348 case MAPDATAUNDERCSET: GET_MAPDATA_VAR_BYTE(undercset); break; //b
6349 case MAPDATACATCHALL: GET_MAPDATA_VAR_INT32(catchall); break; //W
6350
6351 case MAPDATACSENSITIVE: GET_MAPDATA_VAR_BYTE(csensitive); break; //B
6352 case MAPDATANORESET: GET_MAPDATA_VAR_INT32(noreset); break; //W
6353 case MAPDATANOCARRY: GET_MAPDATA_VAR_INT32(nocarry); break; //W
6354 case MAPDATATIMEDWARPTICS: GET_MAPDATA_VAR_INT32(timedwarptics); break; //W
6355 case MAPDATANEXTMAP: GET_MAPDATA_VAR_BYTE(nextmap); break; //B
6356 case MAPDATANEXTSCREEN: GET_MAPDATA_VAR_BYTE(nextscr); break; //B
6357
6358 case MAPDATAVIEWX: break;//GET_MAPDATA_VAR_INT32(viewX, "ViewX"); break; //W
6359 case MAPDATASCRIPT: GET_MAPDATA_VAR_INT32(script); break; //W
6360 case MAPDATAVIEWY: break;//GET_MAPDATA_VAR_INT32(viewY, "ViewY"); break; //W
6361 case MAPDATASCREENWIDTH: break;//GET_MAPDATA_VAR_BYTE(scrWidth, "Width"); break; //B
6362 case MAPDATASCREENHEIGHT: break;//GET_MAPDATA_VAR_BYTE(scrHeight, "Height"); break; //B
6363 case MAPDATAENTRYX: GET_MAPDATA_VAR_BYTE(entry_x); break; //B
6364 case MAPDATAENTRYY: GET_MAPDATA_VAR_BYTE(entry_y); break; //B
6365
6366 //Number of ffcs that are in use (have valid data
6367 // NOTE: defunct. Never implemented correctly.
6368 case MAPDATANUMFF:
6369 {
6370 32 int index = GET_D(rINDEX) / 10000;
6371
6372
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 if (auto handle = ResolveMapdataFFC(ri->mapdataref, index))
6373 {
6374 32 ret = (handle.data() != 0) ? 10000 : 0;
6375 32 }
6376 else
6377 {
6378 ret = 0;
6379 }
6380 32 break;
6381 }
6382
6383 case MAPDATAINTID: //Same form as SetScreenD()
6384 //SetFFCInitD(ffindex, d, value)
6385 {
6386 2004 int32_t index = (GET_D(rINDEX)/10000);
6387 2004 int32_t d_index = GET_D(rINDEX2)/10000;
6388
6389
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2004 times.
2004 if (BC::checkBounds(d_index, 0, 7) != SH::_NoError)
6390 break;
6391
6392
1/2
✓ Branch 0 taken 2004 times.
✗ Branch 1 not taken.
2004 if (auto handle = ResolveMapdataFFC(ri->mapdataref, index))
6393 2004 ret = handle.ffc->initd[d_index];
6394 else
6395 {
6396 ret = -10000;
6397 }
6398 2004 break;
6399 }
6400
6401 case MAPDATASCRIPTENTRY:
6402 {
6403 Z_scripterrlog("Unimplemented: %s\n", "ScriptEntry");
6404 ret = -10000;
6405 }
6406 break;
6407 case MAPDATASCRIPTOCCUPANCY:
6408 {
6409 Z_scripterrlog("Unimplemented: %s\n", "ScriptOccupancy");
6410 ret = -10000;
6411 }
6412 break;
6413 case MAPDATASCRIPTEXIT:
6414 {
6415 Z_scripterrlog("Unimplemented: %s\n", "ExitScript");
6416 ret = -10000;
6417 }
6418 break;
6419
6420 case MAPDATAOCEANSFX: GET_MAPDATA_VAR_BYTE(oceansfx); break; //B
6421 case MAPDATABOSSSFX: GET_MAPDATA_VAR_BYTE(bosssfx); break; //B
6422 case MAPDATASECRETSFX: GET_MAPDATA_VAR_BYTE(secretsfx); break; //B
6423 case MAPDATAHOLDUPSFX: GET_MAPDATA_VAR_BYTE(holdupsfx); break; //B
6424 case MAPDATASCREENMIDI:
6425 {
6426 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
6427 {
6428 ret = ((m->screen_midi+(MIDIOFFSET_MAPSCR-MIDIOFFSET_ZSCRIPT)) *10000);
6429 }
6430 else
6431 {
6432 ret = -10000;
6433 }
6434 break;
6435 }
6436 case MAPDATA_GRAVITY_STRENGTH:
6437 {
6438 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
6439 {
6440 ret = m->screen_gravity.getZLong();
6441 }
6442 else ret = -10000;
6443 break;
6444 }
6445 case MAPDATA_TERMINAL_VELOCITY:
6446 {
6447 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
6448 {
6449 ret = m->screen_terminal_v.getZLong();
6450 }
6451 else ret = -10000;
6452 break;
6453 }
6454 case MAPDATALENSLAYER: GET_MAPDATA_VAR_BYTE(lens_layer); break; //B, OLD QUESTS ONLY?
6455 case MAPDATAMAP:
6456 {
6457
1/2
✓ Branch 0 taken 151527 times.
✗ Branch 1 not taken.
151527 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
6458 {
6459 151527 ret = getMap(GET_REF(mapdataref)) * 10000;
6460 151527 }
6461 else
6462 {
6463 ret = -10000;
6464 }
6465 151527 break;
6466 }
6467 case MAPDATASCREEN:
6468 {
6469
1/2
✓ Branch 0 taken 314379 times.
✗ Branch 1 not taken.
314379 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
6470 {
6471 314379 ret = getScreen(GET_REF(mapdataref)) * 10000;
6472 314379 }
6473 else
6474 {
6475 ret = -10000;
6476 }
6477 314379 break;
6478 }
6479 case MAPDATASCRDATASIZE:
6480 {
6481 ret = -10000;
6482 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
6483 {
6484 int index = get_ref_map_index(GET_REF(mapdataref));
6485 if (index < 0) break;
6486
6487 ret = 10000*game->scriptDataSize(index);
6488 }
6489 break;
6490 }
6491 case MAPDATAGUYCOUNT:
6492 {
6493 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
6494 {
6495 int mi = get_mi(GET_REF(mapdataref));
6496 if(mi > -1)
6497 {
6498 ret = game->guys[mi] * 10000;
6499 break;
6500 }
6501 }
6502 ret = -10000;
6503 break;
6504 }
6505 case MAPDATAEXDOOR:
6506 {
6507 ret = 0;
6508 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
6509 {
6510 int mi = get_mi(GET_REF(mapdataref));
6511 if(mi < 0) break;
6512 int dir = SH::read_stack(ri->sp+1) / 10000;
6513 int ind = SH::read_stack(ri->sp+0) / 10000;
6514 if(unsigned(dir) > 3)
6515 Z_scripterrlog("Invalid dir '%d' passed to 'mapdata->GetExDoor()'; must be 0-3\n", dir);
6516 else if(unsigned(ind) > 7)
6517 Z_scripterrlog("Invalid index '%d' passed to 'mapdata->GetExDoor()'; must be 0-7\n", ind);
6518 else
6519 {
6520 int bit = 1<<ind;
6521 ret = (game->xdoors[mi][dir]&bit) ? 10000 : 0;
6522 }
6523 }
6524 break;
6525 }
6526
6527 ///----------------------------------------------------------------------------------------------------//
6528 //shopdata sd-> variables
6529
6530 case SHOPDATATYPE:
6531 {
6532 int32_t ref = ri->shopdataref;
6533 if ( ref > NUMINFOSHOPS || ref < 0 ) ret = 0;
6534 else ret = ( ( ref <= NUMSHOPS ) ? 10000 : 20000 );
6535 break;
6536 }
6537
6538 ///----------------------------------------------------------------------------------------------------//
6539 //dmapdata dmd-> variables
6540
6541 //getter
6542 1402 case DMAPDATAID: ret = ri->dmapdataref*10000; break; //read-only, equal to CurrentDMap
6543
6544 case DMAPDATAMAP: //byte
6545 {
6546 193590 ret = ((byte)DMaps[GET_REF(dmapdataref)].map + 1) * 10000; break;
6547 }
6548 case DMAPDATALEVEL: //word
6549 {
6550 ret = ((word)DMaps[GET_REF(dmapdataref)].level) * 10000; break;
6551 }
6552 case DMAPDATAFLOOR: //byte
6553 {
6554 ret = ((byte)DMaps[GET_REF(dmapdataref)].floor) * 10000; break;
6555 }
6556 case DMAPDATAOFFSET: //char
6557 {
6558 8824 ret = ((char)DMaps[GET_REF(dmapdataref)].xoff) * 10000; break;
6559 }
6560 case DMAPDATACOMPASS: //byte
6561 {
6562 128960 ret = ((byte)DMaps[GET_REF(dmapdataref)].compass) * 10000; break;
6563 }
6564 case DMAPDATAPALETTE: //word
6565 {
6566 51092 ret = ((word)DMaps[GET_REF(dmapdataref)].color) * 10000; break;
6567 }
6568 case DMAPSCRIPT: //word
6569 {
6570 814 ret = (DMaps[GET_REF(dmapdataref)].script) * 10000; break;
6571 }
6572 case DMAPDATAMIDI: //byte
6573 {
6574 ret = (DMaps[GET_REF(dmapdataref)].midi-MIDIOFFSET_DMAP) * 10000; break;
6575 }
6576 case DMAPDATA_GRAVITY_STRENGTH:
6577 {
6578 ret = DMaps[GET_REF(dmapdataref)].dmap_gravity.getZLong();
6579 break;
6580 }
6581 case DMAPDATA_TERMINAL_VELOCITY:
6582 {
6583 ret = DMaps[GET_REF(dmapdataref)].dmap_terminal_v.getZLong();
6584 break;
6585 }
6586 case DMAPDATACONTINUE: //byte
6587 {
6588 ret = ((byte)DMaps[GET_REF(dmapdataref)].cont) * 10000; break;
6589 }
6590 case DMAPDATATYPE: //byte
6591 {
6592 13125 ret = ((byte)DMaps[GET_REF(dmapdataref)].type&dmfTYPE) * 10000; break;
6593 }
6594 case DMAPDATASIDEVIEW: //byte
6595 {
6596 1192906 ret = ((DMaps[GET_REF(dmapdataref)].sideview) ? 10000 : 0); break;
6597 }
6598 case DMAPDATAMUISCTRACK: //byte
6599 {
6600 ret = ((byte)DMaps[GET_REF(dmapdataref)].tmusictrack) * 10000; break;
6601 }
6602 case DMAPDATASUBSCRA:
6603 {
6604 ret = ((byte)DMaps[GET_REF(dmapdataref)].active_subscreen) * 10000; break;
6605 }
6606 case DMAPDATASUBSCRP:
6607 {
6608 5120 ret = ((byte)DMaps[GET_REF(dmapdataref)].passive_subscreen) * 10000; break;
6609 }
6610 case DMAPDATASUBSCRO:
6611 {
6612 ret = ((byte)DMaps[GET_REF(dmapdataref)].overlay_subscreen) * 10000; break;
6613 }
6614 case DMAPDATAFLAGS: //int32_t
6615 {
6616 ret = (DMaps[GET_REF(dmapdataref)].flags) * 10000; break;
6617 }
6618 case DMAPDATAMIRRDMAP:
6619 {
6620 ret = (DMaps[GET_REF(dmapdataref)].mirrorDMap) * 10000; break;
6621 }
6622 case DMAPDATALOOPSTART:
6623 {
6624 ret = (DMaps[GET_REF(dmapdataref)].tmusic_loop_start); break;
6625 }
6626 case DMAPDATALOOPEND:
6627 {
6628 ret = (DMaps[GET_REF(dmapdataref)].tmusic_loop_end); break;
6629 }
6630 case DMAPDATAXFADEIN:
6631 {
6632 ret = (DMaps[GET_REF(dmapdataref)].tmusic_xfade_in * 10000); break;
6633 }
6634 case DMAPDATAXFADEOUT:
6635 {
6636 ret = (DMaps[GET_REF(dmapdataref)].tmusic_xfade_out * 10000); break;
6637 }
6638 case DMAPDATAINTROSTRINGID:
6639 {
6640 ret = (DMaps[GET_REF(dmapdataref)].intro_string_id * 10000); break;
6641 }
6642 case MUSICUPDATECOND:
6643 {
6644 ret = ((byte)FFCore.music_update_cond) * 10000; break;
6645 }
6646 case DMAPDATAASUBSCRIPT: //word
6647 {
6648 23552 ret = (DMaps[GET_REF(dmapdataref)].active_sub_script) * 10000; break;
6649 }
6650 case DMAPDATAMAPSCRIPT: //byte
6651 {
6652 ret = (DMaps[GET_REF(dmapdataref)].onmap_script) * 10000; break;
6653 }
6654 case DMAPDATAPSUBSCRIPT: //word
6655 {
6656 ret = (DMaps[GET_REF(dmapdataref)].passive_sub_script) * 10000; break;
6657 }
6658
6659 ///----------------------------------------------------------------------------------------------------//
6660 //messagedata msgd-> variables
6661 case MESSAGEDATANEXT: //W
6662 {
6663 int32_t ID = GET_REF(msgdataref);
6664
6665 if(BC::checkMessage(ID) != SH::_NoError)
6666 {
6667 ret = -10000; break;
6668 }
6669 else
6670 {
6671 ret = ((int32_t)MsgStrings[ID].nextstring) * 10000;
6672 break;
6673 }
6674 }
6675
6676 case MESSAGEDATATILE: //W
6677 {
6678 int32_t ID = GET_REF(msgdataref);
6679
6680 if(BC::checkMessage(ID) != SH::_NoError)
6681 ret = -10000;
6682 else
6683 ret = ((int32_t)MsgStrings[ID].tile) * 10000;
6684 break;
6685 }
6686
6687 case MESSAGEDATACSET: //b
6688 {
6689 int32_t ID = GET_REF(msgdataref);
6690
6691 if(BC::checkMessage(ID) != SH::_NoError)
6692 ret = -10000;
6693 else
6694 ret = ((int32_t)MsgStrings[ID].cset) * 10000;
6695 break;
6696 }
6697 case MESSAGEDATATRANS: //BOOL
6698 {
6699 int32_t ID = GET_REF(msgdataref);
6700
6701 if(BC::checkMessage(ID) != SH::_NoError)
6702 ret = -10000;
6703 else
6704 ret = ((MsgStrings[ID].trans)?10000:0);
6705 break;
6706 }
6707 case MESSAGEDATAFONT: //B
6708 {
6709 int32_t ID = GET_REF(msgdataref);
6710
6711 if(BC::checkMessage(ID) != SH::_NoError)
6712 ret = -10000;
6713 else
6714 ret = (int32_t)MsgStrings[ID].font * 10000;
6715 break;
6716 }
6717 case MESSAGEDATAX: //SHORT
6718 {
6719 int32_t ID = GET_REF(msgdataref);
6720
6721 if(BC::checkMessage(ID) != SH::_NoError)
6722 ret = -10000;
6723 else
6724 ret = ((int32_t)MsgStrings[ID].x) * 10000;
6725 break;
6726 }
6727 case MESSAGEDATAY: //SHORT
6728 {
6729 int32_t ID = GET_REF(msgdataref);
6730
6731 if(BC::checkMessage(ID) != SH::_NoError)
6732 ret = -10000;
6733 else
6734 ret = ((int32_t)MsgStrings[ID].y) * 10000;
6735 break;
6736 }
6737 case MESSAGEDATAW: //UNSIGNED SHORT
6738 {
6739 int32_t ID = GET_REF(msgdataref);
6740
6741 if(BC::checkMessage(ID) != SH::_NoError)
6742 ret = -10000;
6743 else
6744 ret = ((int32_t)MsgStrings[ID].w) * 10000;
6745 break;
6746 }
6747 case MESSAGEDATAH: //UNSIGNED SHORT
6748 {
6749 int32_t ID = GET_REF(msgdataref);
6750
6751 if(BC::checkMessage(ID) != SH::_NoError)
6752 ret = -10000;
6753 else
6754 ret = ((int32_t)MsgStrings[ID].h) * 10000;
6755 break;
6756 }
6757 case MESSAGEDATASFX: //BYTE
6758 {
6759 int32_t ID = GET_REF(msgdataref);
6760
6761 if(BC::checkMessage(ID) != SH::_NoError)
6762 ret = -10000;
6763 else
6764 ret = ((int32_t)MsgStrings[ID].sfx) * 10000;
6765 break;
6766 }
6767 case MESSAGEDATALISTPOS: //WORD
6768 {
6769 int32_t ID = GET_REF(msgdataref);
6770
6771 if(BC::checkMessage(ID) != SH::_NoError)
6772 ret = -10000;
6773 else
6774 ret = ((int32_t)MsgStrings[ID].listpos) * 10000;
6775 break;
6776 }
6777 case MESSAGEDATAVSPACE: //BYTE
6778 {
6779 int32_t ID = GET_REF(msgdataref);
6780
6781 if(BC::checkMessage(ID) != SH::_NoError)
6782 ret = -10000;
6783 else
6784 ret = ((int32_t)MsgStrings[ID].vspace) * 10000;
6785 break;
6786 }
6787 case MESSAGEDATAHSPACE: //BYTE
6788 {
6789 int32_t ID = GET_REF(msgdataref);
6790
6791 if(BC::checkMessage(ID) != SH::_NoError)
6792 ret = -10000;
6793 else
6794 ret = ((int32_t)MsgStrings[ID].hspace) * 10000;
6795 break;
6796 }
6797 case MESSAGEDATAFLAGS: //BYTE
6798 {
6799 int32_t ID = GET_REF(msgdataref);
6800
6801 if(BC::checkMessage(ID) != SH::_NoError)
6802 ret = -10000;
6803 else
6804 ret = ((int32_t)MsgStrings[ID].stringflags) * 10000;
6805 break;
6806 }
6807 case MESSAGEDATAPORTTILE: //INT
6808 {
6809 int32_t ID = GET_REF(msgdataref);
6810
6811 if(BC::checkMessage(ID) != SH::_NoError)
6812 ret = -10000;
6813 else
6814 ret = ((int32_t)MsgStrings[ID].portrait_tile) * 10000;
6815 break;
6816 }
6817 case MESSAGEDATAPORTCSET: //BYTE
6818 {
6819 int32_t ID = GET_REF(msgdataref);
6820
6821 if(BC::checkMessage(ID) != SH::_NoError)
6822 ret = -10000;
6823 else
6824 ret = ((int32_t)MsgStrings[ID].portrait_cset) * 10000;
6825 break;
6826 }
6827 case MESSAGEDATAPORTX: //BYTE
6828 {
6829 int32_t ID = GET_REF(msgdataref);
6830
6831 if(BC::checkMessage(ID) != SH::_NoError)
6832 ret = -10000;
6833 else
6834 ret = ((int32_t)MsgStrings[ID].portrait_x) * 10000;
6835 break;
6836 }
6837 case MESSAGEDATAPORTY: //BYTE
6838 {
6839 int32_t ID = GET_REF(msgdataref);
6840
6841 if(BC::checkMessage(ID) != SH::_NoError)
6842 ret = -10000;
6843 else
6844 ret = ((int32_t)MsgStrings[ID].portrait_y) * 10000;
6845 break;
6846 }
6847 case MESSAGEDATAPORTWID: //BYTE
6848 {
6849 int32_t ID = GET_REF(msgdataref);
6850
6851 if(BC::checkMessage(ID) != SH::_NoError)
6852 ret = -10000;
6853 else
6854 ret = ((int32_t)MsgStrings[ID].portrait_tw) * 10000;
6855 break;
6856 }
6857 case MESSAGEDATAPORTHEI: //BYTE
6858 {
6859 int32_t ID = GET_REF(msgdataref);
6860
6861 if(BC::checkMessage(ID) != SH::_NoError)
6862 ret = -10000;
6863 else
6864 ret = ((int32_t)MsgStrings[ID].portrait_th) * 10000;
6865 break;
6866 }
6867 case MESSAGEDATATEXTLEN: //BYTE
6868 {
6869 int32_t ID = GET_REF(msgdataref);
6870
6871 if(BC::checkMessage(ID) != SH::_NoError)
6872 ret = -10000;
6873 else
6874 ret = int32_t(MsgStrings[ID].s.size()) * 10000;
6875 break;
6876 }
6877 case MESSAGEDATATEXTWID:
6878 {
6879 ret = do_msgwidth(GET_REF(msgdataref))*10000;
6880 break;
6881 }
6882 case MESSAGEDATATEXTHEI:
6883 {
6884 ret = do_msgheight(GET_REF(msgdataref))*10000;
6885 break;
6886 }
6887
6888 ///----------------------------------------------------------------------------------------------------//
6889 //combodata cd-> Getter variables
6890 #define GET_COMBO_VAR_INT(member) \
6891 { \
6892 if(!checkComboRef()) \
6893 { \
6894 ret = -10000; \
6895 } \
6896 else \
6897 { \
6898 ret = (combobuf[GET_REF(combodataref)].member *10000); \
6899 } \
6900 } \
6901
6902 #define GET_COMBO_VAR_BYTE(member) \
6903 { \
6904 if(!checkComboRef()) \
6905 { \
6906 ret = -10000; \
6907 } \
6908 else \
6909 { \
6910 ret = (combobuf[GET_REF(combodataref)].member *10000); \
6911 } \
6912 } \
6913
6914 #define GET_COMBO_VAR_DWORD(member) \
6915 { \
6916 if(!checkComboRef()) \
6917 { \
6918 ret = -10000; \
6919 } \
6920 else \
6921 { \
6922 ret = (combobuf[GET_REF(combodataref)].member *10000); \
6923 } \
6924 } \
6925
6926 //comboclass macros
6927
6928 #define GET_COMBOCLASS_VAR_INT(member) \
6929 { \
6930 if(!checkComboRef()) \
6931 { \
6932 ret = -10000; \
6933 } \
6934 else \
6935 { \
6936 ret = (combo_class_buf[combobuf[GET_REF(combodataref)].type].member *10000); \
6937 } \
6938 } \
6939
6940 #define GET_COMBOCLASS_VAR_BYTE(member) \
6941 { \
6942 if(!checkComboRef()) \
6943 { \
6944 ret = -10000; \
6945 } \
6946 else \
6947 { \
6948 ret = (combo_class_buf[combobuf[GET_REF(combodataref)].type].member *10000); \
6949 } \
6950 } \
6951
6952 #define GET_COMBOCLASS_VAR_DWORD(member) \
6953 { \
6954 if(!checkComboRef()) \
6955 { \
6956 ret = -10000; \
6957 } \
6958 else \
6959 { \
6960 ret = (combo_class_buf[combobuf[GET_REF(combodataref)].type].member *10000); \
6961 } \
6962 } \
6963
6964 #define GET_COMBOCLASS_BYTE_INDEX(member, indexbound) \
6965 { \
6966 int32_t indx = GET_D(rINDEX) / 10000; \
6967 if(!checkComboRef()) \
6968 { \
6969 ret = -10000; \
6970 } \
6971 else if ( indx < 0 || indx > indexbound ) \
6972 { \
6973 scripting_log_error_with_context("Invalid Array Index: {}", indx); \
6974 ret = -10000; \
6975 } \
6976 else \
6977 { \
6978 ret = (combo_class_buf[combobuf[GET_REF(combodataref)].type].member[indx] * 100000); \
6979 } \
6980 }
6981
6982 case COMBOXR:
6983 {
6984
1/2
✓ Branch 0 taken 182307 times.
✗ Branch 1 not taken.
182307 if ( curScriptType == ScriptType::Combo )
6985 {
6986 182307 rpos_t rpos = combopos_ref_to_rpos(GET_REF(comboposref));
6987 182307 ret = (( COMBOX_REGION((rpos)) ) * 10000);
6988 //this may be wrong...may need a special new var for this, storing the exact combopos
6989 //i is the current script number
6990 182307 }
6991 else
6992 {
6993 scripting_log_error_with_context("Can only be called by combodata scripts, but you tried to use it from script type {}, name: {}", ScriptTypeToString(curScriptType), curscript->name());
6994 ret = -10000;
6995 }
6996 182307 break;
6997 }
6998
6999 case COMBOYR:
7000 {
7001
1/2
✓ Branch 0 taken 134178 times.
✗ Branch 1 not taken.
134178 if ( curScriptType == ScriptType::Combo )
7002 {
7003 134178 rpos_t rpos = combopos_ref_to_rpos(GET_REF(comboposref));
7004 134178 ret = (( COMBOY_REGION((rpos)) ) * 10000);
7005 134178 }
7006 else
7007 {
7008 scripting_log_error_with_context("Can only be called by combodata scripts, but you tried to use it from script type {}, name: {}", ScriptTypeToString(curScriptType), curscript->name());
7009 ret = -10000;
7010 }
7011 134178 break;
7012 }
7013 case COMBOPOSR:
7014 {
7015
1/2
✓ Branch 0 taken 629336 times.
✗ Branch 1 not taken.
629336 if ( curScriptType == ScriptType::Combo )
7016 {
7017 629336 rpos_t rpos = combopos_ref_to_rpos(GET_REF(comboposref));
7018 629336 ret = (int)rpos * 10000;
7019 629336 }
7020 else
7021 {
7022 scripting_log_error_with_context("Can only be called by combodata scripts, but you tried to use it from script type {}, name: {}", ScriptTypeToString(curScriptType), curscript->name());
7023 ret = -10000;
7024 }
7025 629336 break;
7026 }
7027 case COMBOLAYERR:
7028 {
7029
1/2
✓ Branch 0 taken 19185 times.
✗ Branch 1 not taken.
19185 if ( curScriptType == ScriptType::Combo )
7030 {
7031 19185 int32_t layer = combopos_ref_to_layer(GET_REF(comboposref));
7032 19185 ret = layer * 10000;
7033 19185 }
7034 else
7035 {
7036 scripting_log_error_with_context("Can only be called by combodata scripts, but you tried to use it from script type {}, name: {}", ScriptTypeToString(curScriptType), curscript->name());
7037 ret = -10000;
7038 }
7039 19185 break;
7040 }
7041
7042 //NEWCOMBO STRUCT
7043
1/2
✓ Branch 0 taken 116988 times.
✗ Branch 1 not taken.
116988 case COMBODTILE: GET_COMBO_VAR_DWORD(tile); break; //word
7044
1/2
✓ Branch 0 taken 122133 times.
✗ Branch 1 not taken.
122133 case COMBODOTILE: GET_COMBO_VAR_DWORD(o_tile); break; //word
7045
1/2
✓ Branch 0 taken 9711 times.
✗ Branch 1 not taken.
9711 case COMBODFRAME: GET_COMBO_VAR_BYTE(cur_frame); break; //char
7046 case COMBODACLK: GET_COMBO_VAR_BYTE(aclk); break; //char
7047
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 case COMBODASPEED: GET_COMBO_VAR_BYTE(speed); break; //char
7048
1/2
✓ Branch 0 taken 14257 times.
✗ Branch 1 not taken.
14257 case COMBODFLIP: GET_COMBO_VAR_BYTE(flip); break; //char
7049 case COMBODWALK:
7050 {
7051
1/2
✓ Branch 0 taken 6890 times.
✗ Branch 1 not taken.
6890 if(!checkComboRef())
7052 {
7053 ret = -10000;
7054 }
7055 else
7056 {
7057 6890 ret = ((combobuf[GET_REF(combodataref)].walk&0x0F) *10000);
7058 }
7059 6890 break;
7060 }
7061 case COMBODEFFECT:
7062 {
7063
1/2
✓ Branch 0 taken 755 times.
✗ Branch 1 not taken.
755 if(!checkComboRef())
7064 {
7065 ret = -10000;
7066 }
7067 else
7068 {
7069 755 ret = (((combobuf[GET_REF(combodataref)].walk&0xF0)>>4) *10000);
7070 }
7071 755 break;
7072 }
7073
1/2
✓ Branch 0 taken 12398 times.
✗ Branch 1 not taken.
12398 case COMBODTYPE: GET_COMBO_VAR_BYTE(type); break; //char
7074 case COMBODCSET:
7075 {
7076 if(!checkComboRef())
7077 {
7078 ret = -10000;
7079 }
7080 else
7081 {
7082 bool neg = combobuf[GET_REF(combodataref)].csets&0x8;
7083 ret = ((combobuf[GET_REF(combodataref)].csets&0x7) * (neg ? -10000 : 10000));
7084 }
7085 break;
7086 }
7087 case COMBODCSET2FLAGS:
7088 {
7089 if(checkComboRef())
7090 {
7091 ret = ((combobuf[GET_REF(combodataref)].csets & 0xF0) >> 4) * 10000;
7092 }
7093 break;
7094 }
7095 case COMBODFOO: break; //W
7096
1/2
✓ Branch 0 taken 528885 times.
✗ Branch 1 not taken.
528885 case COMBODATASCRIPT: GET_COMBO_VAR_DWORD(script); break; //W
7097
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 case COMBODFRAMES: GET_COMBO_VAR_BYTE(frames); break; //C
7098 case COMBODNEXTD: GET_COMBO_VAR_INT(nextcombo); break; //W
7099 case COMBODNEXTC: GET_COMBO_VAR_BYTE(nextcset); break; //C
7100 case COMBODFLAG: GET_COMBO_VAR_BYTE(flag); break; //C
7101 case COMBODSKIPANIM: GET_COMBO_VAR_BYTE(skipanim); break; //C
7102 case COMBODNEXTTIMER: GET_COMBO_VAR_DWORD(nexttimer); break; //W
7103 case COMBODAKIMANIMY: GET_COMBO_VAR_BYTE(skipanimy); break; //C
7104
1/2
✓ Branch 0 taken 5429248 times.
✗ Branch 1 not taken.
5429248 case COMBODANIMFLAGS: GET_COMBO_VAR_BYTE(animflags); break; //C
7105
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 case COMBODUSRFLAGS: GET_COMBO_VAR_INT(usrflags); break; //LONG
7106 case COMBODTRIGGERITEM:
7107 {
7108 ret = -10000;
7109 if (!checkComboRef()) break;
7110
7111 if(auto* trig = get_first_combo_trigger())
7112 ret = trig->triggeritem * 10000;
7113 break;
7114 }
7115 case COMBODTRIGGERTIMER:
7116 {
7117 ret = -10000;
7118 if (!checkComboRef()) break;
7119
7120 if(auto* trig = get_first_combo_trigger())
7121 ret = trig->trigtimer * 10000;
7122 break;
7123 }
7124 case COMBODTRIGGERSFX:
7125 {
7126 ret = -10000;
7127 if (!checkComboRef()) break;
7128
7129 if(auto* trig = get_first_combo_trigger())
7130 ret = trig->trigsfx * 10000;
7131 break;
7132 }
7133 case COMBODTRIGGERCHANGECMB:
7134 {
7135 ret = -10000;
7136 if (!checkComboRef()) break;
7137
7138 if(auto* trig = get_first_combo_trigger())
7139 ret = trig->trigchange * 10000;
7140 break;
7141 }
7142 case COMBODTRIGGERPROX:
7143 {
7144 ret = -10000;
7145 if (!checkComboRef()) break;
7146
7147 if(auto* trig = get_first_combo_trigger())
7148 ret = trig->trigprox * 10000;
7149 break;
7150 }
7151 case COMBODTRIGGERLIGHTBEAM:
7152 {
7153 ret = -10000;
7154 if (!checkComboRef()) break;
7155
7156 if(auto* trig = get_first_combo_trigger())
7157 ret = trig->triglbeam * 10000;
7158 break;
7159 }
7160 case COMBODTRIGGERCTR:
7161 {
7162 ret = -10000;
7163 if (!checkComboRef()) break;
7164
7165 if(auto* trig = get_first_combo_trigger())
7166 ret = trig->trigctr * 10000;
7167 break;
7168 }
7169 case COMBODTRIGGERCTRAMNT:
7170 {
7171 ret = -10000;
7172 if (!checkComboRef()) break;
7173
7174 if(auto* trig = get_first_combo_trigger())
7175 ret = trig->trigctramnt * 10000;
7176 break;
7177 }
7178 case COMBODTRIGGERCOOLDOWN:
7179 {
7180 ret = -10000;
7181 if (!checkComboRef()) break;
7182
7183 if(auto* trig = get_first_combo_trigger())
7184 ret = trig->trigcooldown * 10000;
7185 break;
7186 }
7187 case COMBODTRIGGERCOPYCAT:
7188 {
7189 ret = -10000;
7190 if (!checkComboRef()) break;
7191
7192 if(auto* trig = get_first_combo_trigger())
7193 ret = trig->trigcopycat * 10000;
7194 break;
7195 }
7196 case COMBODTRIGITEMPICKUP:
7197 {
7198 ret = -10000;
7199 if (!checkComboRef()) break;
7200
7201 if(auto* trig = get_first_combo_trigger())
7202 ret = trig->spawnip * 10000;
7203 break;
7204 }
7205 case COMBODTRIGEXSTATE:
7206 {
7207 ret = -10000;
7208 if (!checkComboRef()) break;
7209
7210 if(auto* trig = get_first_combo_trigger())
7211 ret = trig->exstate * 10000;
7212 break;
7213 }
7214 case COMBODTRIGEXDOORDIR:
7215 {
7216 ret = -10000;
7217 if (!checkComboRef()) break;
7218
7219 if(auto* trig = get_first_combo_trigger())
7220 ret = trig->exdoor_dir * 10000;
7221 break;
7222 }
7223 case COMBODTRIGEXDOORIND:
7224 {
7225 ret = -10000;
7226 if (!checkComboRef()) break;
7227
7228 if(auto* trig = get_first_combo_trigger())
7229 ret = trig->exdoor_ind * 10000;
7230 break;
7231 }
7232 case COMBODTRIGSPAWNENEMY:
7233 {
7234 ret = -10000;
7235 if (!checkComboRef()) break;
7236
7237 if(auto* trig = get_first_combo_trigger())
7238 ret = trig->spawnenemy * 10000;
7239 break;
7240 }
7241 case COMBODTRIGSPAWNITEM:
7242 {
7243 25 ret = -10000;
7244
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 if (!checkComboRef()) break;
7245
7246
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 if(auto* trig = get_first_combo_trigger())
7247 25 ret = trig->spawnitem * 10000;
7248 25 break;
7249 }
7250 case COMBODTRIGCSETCHANGE:
7251 {
7252 ret = -10000;
7253 if (!checkComboRef()) break;
7254
7255 if(auto* trig = get_first_combo_trigger())
7256 ret = trig->trigcschange * 10000;
7257 break;
7258 }
7259 case COMBODTRIGLITEMS:
7260 {
7261 ret = -10000;
7262 if (!checkComboRef()) break;
7263
7264 if(auto* trig = get_first_combo_trigger())
7265 ret = trig->trig_levelitems * 10000;
7266 break;
7267 }
7268 case COMBODTRIGDMAPLVL:
7269 {
7270 ret = -10000;
7271 if (!checkComboRef()) break;
7272
7273 if(auto* trig = get_first_combo_trigger())
7274 ret = trig->trigdmlevel * 10000;
7275 break;
7276 }
7277 case COMBODTRIGTINTR:
7278 {
7279 if (!checkComboRef()) break;
7280
7281 if(auto* trig = get_first_combo_trigger())
7282 ret = trig->trigtint[0] * 10000;
7283 break;
7284 }
7285 case COMBODTRIGTINTG:
7286 {
7287 if (!checkComboRef()) break;
7288
7289 if(auto* trig = get_first_combo_trigger())
7290 ret = trig->trigtint[1] * 10000;
7291 break;
7292 }
7293 case COMBODTRIGTINTB:
7294 {
7295 if (!checkComboRef()) break;
7296
7297 if(auto* trig = get_first_combo_trigger())
7298 ret = trig->trigtint[2] * 10000;
7299 break;
7300 }
7301 case COMBODTRIGLVLPAL:
7302 {
7303 ret = -10000;
7304 if (!checkComboRef()) break;
7305
7306 if(auto* trig = get_first_combo_trigger())
7307 ret = trig->triglvlpalette * 10000;
7308 break;
7309 }
7310 case COMBODTRIGBOSSPAL:
7311 {
7312 ret = -10000;
7313 if (!checkComboRef()) break;
7314
7315 if(auto* trig = get_first_combo_trigger())
7316 ret = trig->trigbosspalette * 10000;
7317 break;
7318 }
7319 case COMBODTRIGQUAKETIME:
7320 {
7321 ret = -10000;
7322 if (!checkComboRef()) break;
7323
7324 if(auto* trig = get_first_combo_trigger())
7325 ret = trig->trigquaketime * 10000;
7326 break;
7327 }
7328 case COMBODTRIGWAVYTIME:
7329 {
7330 ret = -10000;
7331 if (!checkComboRef()) break;
7332
7333 if(auto* trig = get_first_combo_trigger())
7334 ret = trig->trigwavytime * 10000;
7335 break;
7336 }
7337 case COMBODTRIGSWORDJINX:
7338 {
7339 ret = -10000;
7340 if (!checkComboRef()) break;
7341
7342 if(auto* trig = get_first_combo_trigger())
7343 ret = trig->trig_swjinxtime * 10000;
7344 break;
7345 }
7346 case COMBODTRIGITEMJINX:
7347 {
7348 ret = -10000;
7349 if (!checkComboRef()) break;
7350
7351 if(auto* trig = get_first_combo_trigger())
7352 ret = trig->trig_itmjinxtime * 10000;
7353 break;
7354 }
7355 case COMBODTRIGSHIELDJINX:
7356 {
7357 ret = -10000;
7358 if (!checkComboRef()) break;
7359
7360 if(auto* trig = get_first_combo_trigger())
7361 ret = trig->trig_shieldjinxtime * 10000;
7362 break;
7363 }
7364 case COMBODTRIGSTUN:
7365 {
7366 ret = -10000;
7367 if (!checkComboRef()) break;
7368
7369 if(auto* trig = get_first_combo_trigger())
7370 ret = trig->trig_stuntime * 10000;
7371 break;
7372 }
7373 case COMBODTRIGBUNNY:
7374 {
7375 ret = -10000;
7376 if (!checkComboRef()) break;
7377
7378 if(auto* trig = get_first_combo_trigger())
7379 ret = trig->trig_bunnytime * 10000;
7380 break;
7381 }
7382 case COMBODTRIGPUSHTIME:
7383 {
7384 ret = -10000;
7385 if (!checkComboRef()) break;
7386
7387 if(auto* trig = get_first_combo_trigger())
7388 ret = trig->trig_pushtime * 10000;
7389 break;
7390 }
7391 case COMBODLIFTGFXCOMBO:
7392 {
7393 ret = -10000;
7394 if (!checkComboRef()) break;
7395
7396 ret = (combobuf[GET_REF(combodataref)].liftcmb) * 10000;
7397 break;
7398 }
7399 case COMBODLIFTGFXCCSET:
7400 {
7401 ret = -10000;
7402 if (!checkComboRef()) break;
7403
7404 ret = (combobuf[GET_REF(combodataref)].liftcs) * 10000;
7405 break;
7406 }
7407 case COMBODLIFTUNDERCMB:
7408 {
7409 ret = -10000;
7410 if (!checkComboRef()) break;
7411
7412 ret = (combobuf[GET_REF(combodataref)].liftundercmb) * 10000;
7413 break;
7414 }
7415 case COMBODLIFTUNDERCS:
7416 {
7417 ret = -10000;
7418 if (!checkComboRef()) break;
7419
7420 ret = (combobuf[GET_REF(combodataref)].liftundercs) * 10000;
7421 break;
7422 }
7423 case COMBODLIFTDAMAGE:
7424 {
7425 ret = -10000;
7426 if (!checkComboRef()) break;
7427
7428 ret = (combobuf[GET_REF(combodataref)].liftdmg) * 10000;
7429 break;
7430 }
7431 case COMBODLIFTLEVEL:
7432 {
7433 ret = -10000;
7434 if (!checkComboRef()) break;
7435
7436 ret = (combobuf[GET_REF(combodataref)].liftlvl) * 10000;
7437 break;
7438 }
7439 case COMBODLIFTITEM:
7440 {
7441 ret = -10000;
7442 if (!checkComboRef()) break;
7443
7444 ret = (combobuf[GET_REF(combodataref)].liftitm) * 10000;
7445 break;
7446 }
7447 case COMBODLIFTGFXTYPE:
7448 {
7449 ret = -10000;
7450 if (!checkComboRef()) break;
7451
7452 ret = (combobuf[GET_REF(combodataref)].liftgfx) * 10000;
7453 break;
7454 }
7455 case COMBODLIFTGFXSPRITE:
7456 {
7457 ret = -10000;
7458 if (!checkComboRef()) break;
7459
7460 ret = (combobuf[GET_REF(combodataref)].liftsprite) * 10000;
7461 break;
7462 }
7463 case COMBODLIFTSFX:
7464 {
7465 ret = -10000;
7466 if (!checkComboRef()) break;
7467
7468 ret = (combobuf[GET_REF(combodataref)].liftsfx) * 10000;
7469 break;
7470 }
7471 case COMBODLIFTBREAKSPRITE:
7472 {
7473 ret = -10000;
7474 if (!checkComboRef()) break;
7475
7476 ret = (combobuf[GET_REF(combodataref)].liftbreaksprite) * 10000;
7477 break;
7478 }
7479 case COMBODLIFTBREAKSFX:
7480 {
7481 ret = -10000;
7482 if (!checkComboRef()) break;
7483
7484 ret = (combobuf[GET_REF(combodataref)].liftbreaksfx) * 10000;
7485 break;
7486 }
7487 case COMBODLIFTHEIGHT:
7488 {
7489 ret = -10000;
7490 if (!checkComboRef()) break;
7491
7492 ret = (combobuf[GET_REF(combodataref)].lifthei) * 10000;
7493 break;
7494 }
7495 case COMBODLIFTTIME:
7496 {
7497 ret = -10000;
7498 if (!checkComboRef()) break;
7499
7500 ret = (combobuf[GET_REF(combodataref)].lifttime) * 10000;
7501 break;
7502 }
7503 case COMBODLIFTLIGHTRAD:
7504 {
7505 ret = -10000;
7506 if (!checkComboRef()) break;
7507
7508 ret = (combobuf[GET_REF(combodataref)].lift_weap_data.light_rads[WPNSPR_BASE]) * 10000;
7509 break;
7510 }
7511 case COMBODLIFTLIGHTSHAPE:
7512 {
7513 ret = -10000;
7514 if (!checkComboRef()) break;
7515
7516 ret = (combobuf[GET_REF(combodataref)].lift_weap_data.glow_shape) * 10000;
7517 break;
7518 }
7519 case COMBODLIFTWEAPONITEM:
7520 {
7521 ret = -10000;
7522 if (!checkComboRef()) break;
7523
7524 ret = (combobuf[GET_REF(combodataref)].lift_parent_item) * 10000;
7525 break;
7526 }
7527 case COMBODTRIGGERLSTATE:
7528 {
7529 ret = -10000;
7530 if (!checkComboRef()) break;
7531
7532 if(auto* trig = get_first_combo_trigger())
7533 ret = trig->trig_lstate * 10000;
7534 break;
7535 }
7536 case COMBODTRIGGERGSTATE:
7537 {
7538 ret = -10000;
7539 if (!checkComboRef()) break;
7540
7541 if(auto* trig = get_first_combo_trigger())
7542 ret = trig->trig_gstate * 10000;
7543 break;
7544 }
7545 case COMBODTRIGGERGROUP:
7546 {
7547 ret = -10000;
7548 if (!checkComboRef()) break;
7549
7550 if(auto* trig = get_first_combo_trigger())
7551 ret = trig->trig_group * 10000;
7552 break;
7553 }
7554 case COMBODTRIGGERGROUPVAL:
7555 {
7556 ret = -10000;
7557 if (!checkComboRef()) break;
7558
7559 if(auto* trig = get_first_combo_trigger())
7560 ret = trig->trig_group_val * 10000;
7561 break;
7562 }
7563 case COMBODTRIGGERGTIMER:
7564 {
7565 ret = -10000;
7566 if (!checkComboRef()) break;
7567
7568 if(auto* trig = get_first_combo_trigger())
7569 ret = trig->trig_statetime * 10000;
7570 break;
7571 }
7572 case COMBODTRIGGERGENSCRIPT:
7573 {
7574 ret = -10000;
7575 if (!checkComboRef()) break;
7576
7577 if(auto* trig = get_first_combo_trigger())
7578 ret = trig->trig_genscr * 10000;
7579 break;
7580 }
7581
7582 case COMBODTRIGGERLEVEL:
7583 {
7584 ret = -10000;
7585 if (!checkComboRef()) break;
7586
7587 if(auto* trig = get_first_combo_trigger())
7588 ret = trig->triggerlevel * 10000;
7589 break;
7590 }
7591 5246834 case COMBODATAID: ret = (GET_REF(combodataref)*10000); break;
7592 case COMBODNUMTRIGGERS:
7593 {
7594 ret = -10000;
7595 if (!checkComboRef()) break;
7596
7597 ret = combobuf[GET_REF(combodataref)].triggers.size() * 10000;
7598 break;
7599 }
7600 case COMBODONLYGEN:
7601 {
7602 ret = 0;
7603 if (!checkComboRef()) break;
7604
7605 ret = combobuf[GET_REF(combodataref)].only_gentrig ? 10000 : 0;
7606 break;
7607 }
7608 case COMBOD_Z_HEIGHT:
7609 {
7610 ret = 0;
7611 if (!checkComboRef()) break;
7612
7613 ret = combobuf[GET_REF(combodataref)].z_height.getZLong();
7614 break;
7615 }
7616 case COMBOD_Z_STEP_HEIGHT:
7617 {
7618 ret = 0;
7619 if (!checkComboRef()) break;
7620
7621 ret = combobuf[GET_REF(combodataref)].z_step_height.getZLong();
7622 break;
7623 }
7624 case COMBOD_DIVE_UNDER_LEVEL:
7625 {
7626 ret = 0;
7627 if (!checkComboRef()) break;
7628
7629 ret = combobuf[GET_REF(combodataref)].dive_under_level * 10000;
7630 break;
7631 }
7632 //COMBOCLASS STRUCT
7633 //case COMBODNAME: //CHAR[64], STRING
7634 case COMBODBLOCKNPC: GET_COMBOCLASS_VAR_BYTE(block_enemies); break; //C
7635 case COMBODBLOCKHOLE: GET_COMBOCLASS_VAR_BYTE(block_hole); break; //C
7636 case COMBODBLOCKTRIG: GET_COMBOCLASS_VAR_BYTE(block_trigger); break; //C
7637 case COMBODBLOCKWEAPON: GET_COMBOCLASS_BYTE_INDEX(block_weapon, 32); break; //C, 32 INDICES
7638 case COMBODCONVXSPEED: GET_COMBOCLASS_VAR_DWORD(conveyor_x_speed); break; //SHORT
7639 case COMBODCONVYSPEED: GET_COMBOCLASS_VAR_DWORD(conveyor_y_speed); break; //SHORT
7640 case COMBODSPAWNNPC: GET_COMBOCLASS_VAR_DWORD(create_enemy); break; //W
7641 case COMBODSPAWNNPCWHEN: GET_COMBOCLASS_VAR_BYTE(create_enemy_when); break; //C
7642 case COMBODSPAWNNPCCHANGE: GET_COMBOCLASS_VAR_INT(create_enemy_change); break; //LONG
7643 case COMBODDIRCHANGETYPE: GET_COMBOCLASS_VAR_BYTE(directional_change_type); break; //C
7644 case COMBODDISTANCECHANGETILES: GET_COMBOCLASS_VAR_INT(distance_change_tiles); break; //LONG
7645 case COMBODDIVEITEM: GET_COMBOCLASS_VAR_DWORD(dive_item); break; //SHORT
7646 case COMBODDOCK: GET_COMBOCLASS_VAR_BYTE(dock); break; //C
7647 case COMBODFAIRY: GET_COMBOCLASS_VAR_BYTE(fairy); break; //C
7648 case COMBODFFATTRCHANGE: GET_COMBOCLASS_VAR_BYTE(ff_combo_attr_change); break; //C
7649 case COMBODFOORDECOTILE: GET_COMBOCLASS_VAR_INT(foot_decorations_tile); break; //LONG
7650 case COMBODFOORDECOTYPE: GET_COMBOCLASS_VAR_BYTE(foot_decorations_type); break; //C
7651 case COMBODHOOKSHOTPOINT: GET_COMBOCLASS_VAR_BYTE(hookshot_grab_point); break; //C
7652 case COMBODLADDERPASS: GET_COMBOCLASS_VAR_BYTE(ladder_pass); break; //C
7653 case COMBODLOCKBLOCK: GET_COMBOCLASS_VAR_BYTE(lock_block_type); break; //C
7654 case COMBODLOCKBLOCKCHANGE: GET_COMBOCLASS_VAR_INT(lock_block_change); break; //LONG
7655 case COMBODMAGICMIRROR: GET_COMBOCLASS_VAR_BYTE(magic_mirror_type); break; //C
7656 case COMBODMODHPAMOUNT: GET_COMBOCLASS_VAR_DWORD(modify_hp_amount); break; //SHORT
7657 case COMBODMODHPDELAY: GET_COMBOCLASS_VAR_BYTE(modify_hp_delay); break; //C
7658 case COMBODMODHPTYPE: GET_COMBOCLASS_VAR_BYTE(modify_hp_type); break; //C
7659 case COMBODNMODMPAMOUNT: GET_COMBOCLASS_VAR_DWORD(modify_mp_amount); break; //SHORT
7660 case COMBODMODMPDELAY: GET_COMBOCLASS_VAR_BYTE(modify_mp_delay); break; //C
7661 case COMBODMODMPTYPE: GET_COMBOCLASS_VAR_BYTE(modify_mp_type); break; //C
7662 case COMBODNOPUSHBLOCK: GET_COMBOCLASS_VAR_BYTE(no_push_blocks); break; //C
7663 case COMBODOVERHEAD: GET_COMBOCLASS_VAR_BYTE(overhead); break; //C
7664 case COMBODPLACENPC: GET_COMBOCLASS_VAR_BYTE(place_enemy); break; //C
7665 case COMBODPUSHDIR: GET_COMBOCLASS_VAR_BYTE(push_direction); break; //C
7666 case COMBODPUSHWAIT: GET_COMBOCLASS_VAR_BYTE(push_wait); break; //C
7667 case COMBODPUSHHEAVY: GET_COMBOCLASS_VAR_BYTE(push_weight); break; //C
7668 case COMBODPUSHED: GET_COMBOCLASS_VAR_BYTE(pushed); break; //C
7669 case COMBODRAFT: GET_COMBOCLASS_VAR_BYTE(raft); break; //C
7670 case COMBODRESETROOM: GET_COMBOCLASS_VAR_BYTE(reset_room); break; //C
7671 case COMBODSAVEPOINTTYPE: GET_COMBOCLASS_VAR_BYTE(save_point_type); break; //C
7672 case COMBODSCREENFREEZETYPE: GET_COMBOCLASS_VAR_BYTE(screen_freeze_type); break; //C
7673 case COMBODSECRETCOMBO: GET_COMBOCLASS_VAR_BYTE(secret_combo); break; //C
7674 case COMBODSINGULAR: GET_COMBOCLASS_VAR_BYTE(singular); break; //C
7675 case COMBODSLOWWALK: GET_COMBOCLASS_VAR_BYTE(slow_movement); break; //C
7676 case COMBODSTATUETYPE: GET_COMBOCLASS_VAR_BYTE(statue_type); break; //C
7677 case COMBODSTEPTYPE: GET_COMBOCLASS_VAR_BYTE(step_type); break; //C
7678 case COMBODSTEPCHANGEINTO: GET_COMBOCLASS_VAR_INT(step_change_to); break; //LONG
7679 case COMBODSTRIKEWEAPONS: GET_COMBOCLASS_BYTE_INDEX(strike_weapons, 32); break; //BYTE, 32 INDICES.
7680 case COMBODSTRIKEREMNANTS: GET_COMBOCLASS_VAR_INT(strike_remnants); break; //LONG
7681 case COMBODSTRIKEREMNANTSTYPE: GET_COMBOCLASS_VAR_BYTE(strike_remnants_type); break; //C
7682 case COMBODSTRIKECHANGE: GET_COMBOCLASS_VAR_INT(strike_change); break; //LONG
7683 case COMBODSTRIKEITEM: GET_COMBOCLASS_VAR_DWORD(strike_item); break; //SHORT
7684 case COMBODTOUCHITEM: GET_COMBOCLASS_VAR_DWORD(touch_item); break; //SHORT
7685 case COMBODTOUCHSTAIRS: GET_COMBOCLASS_VAR_BYTE(touch_stairs); break; //C
7686 case COMBODTRIGGERTYPE: GET_COMBOCLASS_VAR_BYTE(trigger_type); break; //C
7687 case COMBODTRIGGERSENS: GET_COMBOCLASS_VAR_BYTE(trigger_sensitive); break; //C
7688 case COMBODWARPTYPE: GET_COMBOCLASS_VAR_BYTE(warp_type); break; //C
7689 case COMBODWARPSENS: GET_COMBOCLASS_VAR_BYTE(warp_sensitive); break; //C
7690 case COMBODWARPDIRECT: GET_COMBOCLASS_VAR_BYTE(warp_direct); break; //C
7691 case COMBODWARPLOCATION: GET_COMBOCLASS_VAR_BYTE(warp_location); break; //C
7692 case COMBODWATER: GET_COMBOCLASS_VAR_BYTE(water); break; //C
7693 case COMBODWHISTLE: GET_COMBOCLASS_VAR_BYTE(whistle); break; //C
7694 case COMBODWINGAME: GET_COMBOCLASS_VAR_BYTE(win_game); break; //C
7695 case COMBODBLOCKWPNLEVEL: GET_COMBOCLASS_VAR_BYTE(block_weapon_lvl); break; //C
7696
7697
7698
7699 ///----------------------------------------------------------------------------------------------------//
7700 case CMBTRIGWPNLEVEL:
7701 {
7702 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7703 {
7704 ret = trig->triggerlevel * 10000;
7705 }
7706 else ret = -10000;
7707 break;
7708 }
7709 case CMBTRIGREQITEM:
7710 {
7711 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7712 {
7713 ret = trig->triggeritem * 10000;
7714 }
7715 else ret = -10000;
7716 break;
7717 }
7718 case CMBTRIGTIMER:
7719 {
7720 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7721 {
7722 ret = trig->trigtimer * 10000;
7723 }
7724 else ret = -10000;
7725 break;
7726 }
7727 case CMBTRIGSFX:
7728 {
7729 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7730 {
7731 ret = trig->trigsfx * 10000;
7732 }
7733 else ret = -10000;
7734 break;
7735 }
7736 case CMBTRIGCHANGECMB:
7737 {
7738 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7739 {
7740 ret = trig->trigchange * 10000;
7741 }
7742 else ret = -10000;
7743 break;
7744 }
7745 case CMBTRIGCSETCHANGE:
7746 {
7747 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7748 {
7749 ret = trig->trigcschange * 10000;
7750 }
7751 else ret = -10000;
7752 break;
7753 }
7754 case CMBTRIGPROX:
7755 {
7756 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7757 {
7758 ret = trig->trigprox * 10000;
7759 }
7760 else ret = -10000;
7761 break;
7762 }
7763 case CMBTRIGLIGHTBEAM:
7764 {
7765 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7766 {
7767 ret = trig->triglbeam * 10000;
7768 }
7769 else ret = -10000;
7770 break;
7771 }
7772 case CMBTRIGCTR:
7773 {
7774 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7775 {
7776 ret = trig->trigctr * 10000;
7777 }
7778 else ret = -10000;
7779 break;
7780 }
7781 case CMBTRIGCTRAMNT:
7782 {
7783 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7784 {
7785 ret = trig->trigctramnt * 10000;
7786 }
7787 else ret = -10000;
7788 break;
7789 }
7790 case CMBTRIGCOOLDOWN:
7791 {
7792 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7793 {
7794 ret = trig->trigcooldown * 10000;
7795 }
7796 else ret = -10000;
7797 break;
7798 }
7799 case CMBTRIGCOPYCAT:
7800 {
7801 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7802 {
7803 ret = trig->trigcopycat * 10000;
7804 }
7805 else ret = -10000;
7806 break;
7807 }
7808 case CMBTRIGITEMPICKUP:
7809 {
7810 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7811 {
7812 ret = trig->spawnip * 10000;
7813 }
7814 else ret = -10000;
7815 break;
7816 }
7817 case CMBTRIGEXSTATE:
7818 {
7819 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7820 {
7821 ret = trig->exstate * 10000;
7822 }
7823 else ret = -10000;
7824 break;
7825 }
7826 case CMBTRIGEXDOORDIR:
7827 {
7828 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7829 {
7830 ret = trig->exdoor_dir * 10000;
7831 }
7832 else ret = -10000;
7833 break;
7834 }
7835 case CMBTRIGEXDOORIND:
7836 {
7837 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7838 {
7839 ret = trig->exdoor_ind * 10000;
7840 }
7841 else ret = -10000;
7842 break;
7843 }
7844 case CMBTRIGSPAWNENEMY:
7845 {
7846 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7847 {
7848 ret = trig->spawnenemy * 10000;
7849 }
7850 else ret = -10000;
7851 break;
7852 }
7853 case CMBTRIGSPAWNITEM:
7854 {
7855 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7856 {
7857 ret = trig->spawnitem * 10000;
7858 }
7859 else ret = -10000;
7860 break;
7861 }
7862 case CMBTRIGLSTATE:
7863 {
7864 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7865 {
7866 ret = trig->trig_lstate * 10000;
7867 }
7868 else ret = -10000;
7869 break;
7870 }
7871 case CMBTRIGGSTATE:
7872 {
7873 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7874 {
7875 ret = trig->trig_gstate * 10000;
7876 }
7877 else ret = -10000;
7878 break;
7879 }
7880 case CMBTRIGGTIMER:
7881 {
7882 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7883 {
7884 ret = trig->trig_statetime * 10000;
7885 }
7886 else ret = -10000;
7887 break;
7888 }
7889 case CMBTRIGGENSCRIPT:
7890 {
7891 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7892 {
7893 ret = trig->trig_genscr * 10000;
7894 }
7895 else ret = -10000;
7896 break;
7897 }
7898 case CMBTRIGGROUP:
7899 {
7900 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7901 {
7902 ret = trig->trig_group * 10000;
7903 }
7904 else ret = -10000;
7905 break;
7906 }
7907 case CMBTRIGGROUPVAL:
7908 {
7909 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7910 {
7911 ret = trig->trig_group_val * 10000;
7912 }
7913 else ret = -10000;
7914 break;
7915 }
7916 case CMBTRIGLITEMS:
7917 {
7918 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7919 {
7920 ret = trig->trig_levelitems * 10000;
7921 }
7922 else ret = -10000;
7923 break;
7924 }
7925 case CMBTRIGDMAPLVL:
7926 {
7927 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7928 {
7929 ret = trig->trigdmlevel * 10000;
7930 }
7931 else ret = -10000;
7932 break;
7933 }
7934 case CMBTRIGREQSTATEMAP:
7935 {
7936 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7937 {
7938 ret = trig->trigstatemap * 10000;
7939 }
7940 else ret = -10000;
7941 break;
7942 }
7943 case CMBTRIGREQSTATESCREEN:
7944 {
7945 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7946 {
7947 ret = trig->trigstatescreen * 10000;
7948 }
7949 else ret = -10000;
7950 break;
7951 }
7952 case CMBTRIGTINTR:
7953 {
7954 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7955 {
7956 ret = trig->trigtint[0] * 10000;
7957 }
7958 else ret = -10000;
7959 break;
7960 }
7961 case CMBTRIGTINTG:
7962 {
7963 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7964 {
7965 ret = trig->trigtint[1] * 10000;
7966 }
7967 else ret = -10000;
7968 break;
7969 }
7970 case CMBTRIGTINTB:
7971 {
7972 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7973 {
7974 ret = trig->trigtint[2] * 10000;
7975 }
7976 else ret = -10000;
7977 break;
7978 }
7979 case CMBTRIGLVLPAL:
7980 {
7981 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7982 {
7983 ret = trig->triglvlpalette * 10000;
7984 }
7985 else ret = -10000;
7986 break;
7987 }
7988 case CMBTRIGBOSSPAL:
7989 {
7990 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7991 {
7992 ret = trig->trigbosspalette * 10000;
7993 }
7994 else ret = -10000;
7995 break;
7996 }
7997 case CMBTRIGQUAKETIME:
7998 {
7999 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8000 {
8001 ret = trig->trigquaketime * 10000;
8002 }
8003 else ret = -10000;
8004 break;
8005 }
8006 case CMBTRIGWAVYTIME:
8007 {
8008 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8009 {
8010 ret = trig->trigwavytime * 10000;
8011 }
8012 else ret = -10000;
8013 break;
8014 }
8015 case CMBTRIGSWORDJINX:
8016 {
8017 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8018 {
8019 ret = trig->trig_swjinxtime * 10000;
8020 }
8021 else ret = -10000;
8022 break;
8023 }
8024 case CMBTRIGITEMJINX:
8025 {
8026 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8027 {
8028 ret = trig->trig_itmjinxtime * 10000;
8029 }
8030 else ret = -10000;
8031 break;
8032 }
8033 case CMBTRIGSHIELDJINX:
8034 {
8035 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8036 {
8037 ret = trig->trig_shieldjinxtime * 10000;
8038 }
8039 else ret = -10000;
8040 break;
8041 }
8042 case CMBTRIGSTUN:
8043 {
8044 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8045 {
8046 ret = trig->trig_stuntime * 10000;
8047 }
8048 else ret = -10000;
8049 break;
8050 }
8051 case CMBTRIGBUNNY:
8052 {
8053 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8054 {
8055 ret = trig->trig_bunnytime * 10000;
8056 }
8057 else ret = -10000;
8058 break;
8059 }
8060 case CMBTRIGPUSHTIME:
8061 {
8062 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8063 {
8064 ret = trig->trig_pushtime * 10000;
8065 }
8066 else ret = -10000;
8067 break;
8068 }
8069 case CMBTRIGGERPROMPTCID:
8070 {
8071 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8072 ret = trig->prompt_cid * 10000;
8073 else ret = -10000;
8074 break;
8075 }
8076 case CMBTRIGGERPROMPTCS:
8077 {
8078 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8079 ret = trig->prompt_cs * 10000;
8080 else ret = -10000;
8081 break;
8082 }
8083 case CMBTRIGGERFAILPROMPTCID:
8084 {
8085 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8086 ret = trig->fail_prompt_cid * 10000;
8087 else ret = -10000;
8088 break;
8089 }
8090 case CMBTRIGGERFAILPROMPTCS:
8091 {
8092 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8093 ret = trig->fail_prompt_cs * 10000;
8094 else ret = -10000;
8095 break;
8096 }
8097 case CMBTRIGGERPROMPTX:
8098 {
8099 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8100 ret = trig->prompt_x * 10000;
8101 else ret = -10000;
8102 break;
8103 }
8104 case CMBTRIGGERPROMPTY:
8105 {
8106 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8107 ret = trig->prompt_y * 10000;
8108 else ret = -10000;
8109 break;
8110 }
8111 case CMBTRIGGERTRIGSTR:
8112 {
8113 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8114 ret = trig->trig_msgstr * 10000;
8115 else ret = -10000;
8116 break;
8117 }
8118 case CMBTRIGGERFAILSTR:
8119 {
8120 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8121 ret = trig->fail_msgstr * 10000;
8122 else ret = -10000;
8123 break;
8124 }
8125 case CMBTRIGGERPLAYERBOUNCE:
8126 {
8127 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8128 ret = trig->player_bounce;
8129 else ret = -10000;
8130 break;
8131 }
8132 case CMBTRIGGERREQPLAYERZ:
8133 {
8134 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8135 ret = trig->req_player_z;
8136 else ret = -10000;
8137 break;
8138 }
8139 case CMBTRIGGERDESTHEROX:
8140 {
8141 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8142 ret = trig->dest_player_x;
8143 else ret = -10000;
8144 break;
8145 }
8146 case CMBTRIGGERDESTHEROY:
8147 {
8148 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8149 ret = trig->dest_player_y;
8150 else ret = -10000;
8151 break;
8152 }
8153 case CMBTRIGGERDESTHEROZ:
8154 {
8155 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8156 ret = trig->dest_player_z;
8157 else ret = -10000;
8158 break;
8159 }
8160 case CMBTRIGGERREQPLAYERJUMP:
8161 {
8162 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8163 ret = trig->req_player_jump;
8164 else ret = -10000;
8165 break;
8166 }
8167 case CMBTRIGGERREQPLAYERX:
8168 {
8169 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8170 ret = trig->req_player_x;
8171 else ret = -10000;
8172 break;
8173 }
8174 case CMBTRIGGERREQPLAYERY:
8175 {
8176 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8177 ret = trig->req_player_y;
8178 else ret = -10000;
8179 break;
8180 }
8181 case CMBTRIGGERFORCEPLAYERDIR:
8182 {
8183 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8184 ret = trig->dest_player_dir * 10000;
8185 else ret = -10000;
8186 break;
8187 }
8188 case CMBTRIGGERICECOMBO:
8189 {
8190 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8191 ret = trig->force_ice_combo * 10000;
8192 else ret = -10000;
8193 break;
8194 }
8195 case CMBTRIGGERICEVX:
8196 {
8197 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8198 ret = trig->force_ice_vx;
8199 else ret = -10000;
8200 break;
8201 }
8202 case CMBTRIGGERICEVY:
8203 {
8204 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8205 ret = trig->force_ice_vy;
8206 else ret = -10000;
8207 break;
8208 }
8209 case CMBTRIGGER_GRAVITY:
8210 {
8211 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8212 ret = trig->trig_gravity;
8213 else ret = -10000;
8214 break;
8215 break;
8216 }
8217 case CMBTRIGGER_TERMINAL_VELOCITY:
8218 {
8219 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8220 ret = trig->trig_terminal_v;
8221 else ret = -10000;
8222 break;
8223 }
8224 ///----------------------------------------------------------------------------------------------------//
8225 //npcdata nd-> variables
8226
8227 //npcdata nd->member variable
8228 #define GET_NPCDATA_VAR_INT32(member, str) \
8229 { \
8230 if( !checkNPCDataRef() ) \
8231 { \
8232 ret = -10000; \
8233 } \
8234 else \
8235 { \
8236 ret = (guysbuf[GET_REF(npcdataref)].member *10000); \
8237 } \
8238 } \
8239
8240 #define GET_NPCDATA_VAR_BYTE(member, str) \
8241 { \
8242 if( !checkNPCDataRef() ) \
8243 { \
8244 ret = -10000; \
8245 } \
8246 else \
8247 { \
8248 ret = (guysbuf[GET_REF(npcdataref)].member *10000); \
8249 } \
8250 } \
8251
8252 #define GET_NPCDATA_VAR_INT16(member, str) \
8253 { \
8254 if( !checkNPCDataRef() ) \
8255 { \
8256 ret = -10000; \
8257 } \
8258 else \
8259 { \
8260 ret = (guysbuf[GET_REF(npcdataref)].member *10000); \
8261 } \
8262 } \
8263
8264 #define GET_NPCDATA_FLAG(member, str, indexbound) \
8265 { \
8266 int32_t flag = (value/10000); \
8267 if( !checkNPCDataRef() ) \
8268 { \
8269 } \
8270 else \
8271 { \
8272 ret = (guysbuf[ID].member&flag) ? 10000 : 0); \
8273 } \
8274 } \
8275
8276 // These are for compat only, though seemingly no quests even use these.
8277 case NPCDATAFLAGS1:
8278 {
8279 if( !checkNPCDataRef() )
8280 {
8281 ret = -10000;
8282 }
8283 else
8284 {
8285 uint32_t value = guysbuf[GET_REF(npcdataref)].flags & 0xFFFFFFFFLL;
8286 ret = value * 10000;
8287 }
8288 }
8289 break;
8290 case NPCDATAFLAGS2:
8291 {
8292 if( !checkNPCDataRef() )
8293 {
8294 ret = -10000;
8295 }
8296 else
8297 {
8298 uint32_t value = (guysbuf[GET_REF(npcdataref)].flags >> 32) & 0xFFFFFFFFLL;
8299 ret = value * 10000;
8300 }
8301 }
8302 break;
8303
8304 case NPCDATATILE: GET_NPCDATA_VAR_BYTE(tile, "Tile"); break;
8305 case NPCDATAWIDTH: GET_NPCDATA_VAR_BYTE(width, "Width"); break;
8306 case NPCDATAHEIGHT: GET_NPCDATA_VAR_BYTE(height, "Height"); break;
8307 case NPCDATASTILE: GET_NPCDATA_VAR_BYTE(s_tile, "STile"); break;
8308 case NPCDATASWIDTH: GET_NPCDATA_VAR_BYTE(s_width, "SWidth"); break;
8309 case NPCDATASHEIGHT: GET_NPCDATA_VAR_BYTE(s_height, "SHeight"); break;
8310
1/2
✓ Branch 0 taken 3182 times.
✗ Branch 1 not taken.
3182 case NPCDATAETILE: GET_NPCDATA_VAR_INT32(e_tile, "ExTile"); break;
8311 case NPCDATAEWIDTH: GET_NPCDATA_VAR_BYTE(e_width, "ExWidth"); break;
8312 case NPCDATAEHEIGHT: GET_NPCDATA_VAR_BYTE(e_height, "ExHeight"); break;
8313 case NPCDATAHP: GET_NPCDATA_VAR_INT16(hp, "HP"); break;
8314 case NPCDATATYPE: GET_NPCDATA_VAR_INT16(type, "Family"); break;
8315
1/2
✓ Branch 0 taken 3182 times.
✗ Branch 1 not taken.
3182 case NPCDATACSET: GET_NPCDATA_VAR_INT16(cset, "CSet"); break;
8316 case NPCDATAANIM: GET_NPCDATA_VAR_INT16(anim, "Anim"); break;
8317 case NPCDATAEANIM: GET_NPCDATA_VAR_INT16(e_anim, "ExAnim"); break;
8318 case NPCDATAFRAMERATE: GET_NPCDATA_VAR_INT16(frate, "Framerate"); break;
8319 case NPCDATAEFRAMERATE: GET_NPCDATA_VAR_INT16(e_frate, "ExFramerate"); break;
8320 case NPCDATATOUCHDAMAGE: GET_NPCDATA_VAR_INT16(dp, "TouchDamage"); break;
8321 case NPCDATAWEAPONDAMAGE: GET_NPCDATA_VAR_INT16(wdp, "WeaponDamage"); break;
8322 case NPCDATAWEAPON: GET_NPCDATA_VAR_INT16(weapon, "Weapon"); break;
8323 case NPCDATARANDOM: GET_NPCDATA_VAR_INT16(rate, "Random"); break;
8324 case NPCDATAHALT: GET_NPCDATA_VAR_INT16(hrate, "Haltrate"); break;
8325 case NPCDATASTEP: GET_NPCDATA_VAR_INT16(step, "Step"); break;
8326 case NPCDATAHOMING: GET_NPCDATA_VAR_INT16(homing, "Homing"); break;
8327 case NPCDATAHUNGER: GET_NPCDATA_VAR_INT16(grumble, "Hunger"); break;
8328 case NPCDATADROPSET: GET_NPCDATA_VAR_INT16(item_set, "Dropset"); break;
8329 case NPCDATABGSFX: GET_NPCDATA_VAR_INT16(bgsfx, "BGSFX"); break;
8330
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 case NPCDATADEATHSFX: GET_NPCDATA_VAR_BYTE(deadsfx, "DeathSFX"); break;
8331
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 case NPCDATAHITSFX: GET_NPCDATA_VAR_BYTE(hitsfx, "HitSFX"); break;
8332 case NPCDATAXOFS: GET_NPCDATA_VAR_INT32(xofs, "DrawXOffset"); break;
8333 case NPCDATAYOFS: GET_NPCDATA_VAR_INT32(yofs, "DrawYOffset"); break;
8334 case NPCDATAZOFS: GET_NPCDATA_VAR_INT32(zofs, "DrawZOffset"); break;
8335 case NPCDATAHXOFS: GET_NPCDATA_VAR_INT32(hxofs, "HitXOffset"); break;
8336 case NPCDATAHYOFS: GET_NPCDATA_VAR_INT32(hyofs, "HitYOffset"); break;
8337 case NPCDATAHITWIDTH: GET_NPCDATA_VAR_INT32(hxsz, "HitWidth"); break;
8338 case NPCDATAHITHEIGHT: GET_NPCDATA_VAR_INT32(hysz, "HitHeight"); break;
8339 case NPCDATAHITZ: GET_NPCDATA_VAR_INT32(hzsz, "HitZHeight"); break;
8340 case NPCDATASCRIPT: GET_NPCDATA_VAR_INT32(script, "Script"); break;
8341 case NPCDATATILEWIDTH: GET_NPCDATA_VAR_INT32(txsz, "TileWidth"); break;
8342 case NPCDATATILEHEIGHT: GET_NPCDATA_VAR_INT32(tysz, "TileHeight"); break;
8343 case NPCDATAWPNSPRITE: GET_NPCDATA_VAR_INT32(wpnsprite, "WeaponSprite"); break;
8344 case NPCDATAWEAPONSCRIPT:
8345 {
8346 if( (unsigned) ri->npcdataref > (MAXNPCS-1) )
8347 {
8348 Z_scripterrlog("Invalid NPC ID passed to npcdata->WeaponScript: %d\n", ri->npcdataref);
8349 ret = -10000;
8350 }
8351 else ret = (guysbuf[GET_REF(npcdataref)].weap_data.script *10000);
8352 break;
8353 }
8354 case NPCDATASIZEFLAG: GET_NPCDATA_VAR_INT32(SIZEflags, "SizeFlags"); break;
8355
8356 case NPCDATAFROZENTILE: GET_NPCDATA_VAR_INT32(frozentile, "FrozenTile"); break;
8357 case NPCDATAFROZENCSET: GET_NPCDATA_VAR_INT32(frozencset, "FrozenCSet"); break;
8358 case NPCDATAFIRESFX: GET_NPCDATA_VAR_BYTE(firesfx, "WeaponSFX"); break;
8359
8360 case NPCDSHADOWSPR:
8361 {
8362 if(!checkNPCDataRef())
8363 {
8364 Z_scripterrlog("Invalid NPC ID passed to npcdata->ShadowSprite: %d\n", ri->npcdataref);
8365 ret = -10000;
8366 }
8367 else
8368 {
8369 ret = guysbuf[GET_REF(npcdataref)].spr_shadow * 10000;
8370 }
8371 break;
8372 }
8373 case NPCDSPAWNSPR:
8374 {
8375 if(!checkNPCDataRef())
8376 {
8377 Z_scripterrlog("Invalid NPC ID passed to npcdata->SpawnSprite: %d\n", ri->npcdataref);
8378 ret = -10000;
8379 }
8380 else
8381 {
8382 ret = guysbuf[GET_REF(npcdataref)].spr_spawn * 10000;
8383 }
8384 break;
8385 }
8386 case NPCDDEATHSPR:
8387 {
8388 if(!checkNPCDataRef())
8389 {
8390 Z_scripterrlog("Invalid NPC ID passed to npcdata->DeathSprite: %d\n", ri->npcdataref);
8391 ret = -10000;
8392 }
8393 else
8394 {
8395 ret = guysbuf[GET_REF(npcdataref)].spr_death * 10000;
8396 }
8397 break;
8398 }
8399
8400 case NPCMATCHINITDLABEL: //Same form as SetScreenD()
8401 //bool npcdata->MatchInitDLabel("label", d)
8402 {
8403
8404 if( !checkNPCDataRef() ) \
8405 {
8406 Z_scripterrlog("Invalid NPC ID passed to npcdata->%s: %d\n", "MatchInitDLabel()", GET_REF(npcdataref));
8407 ret = 0;
8408 break;
8409 }
8410
8411 int32_t arrayptr = get_register(sarg1);
8412 int32_t init_d_index = get_register(sarg2) / 10000;
8413
8414 string name;
8415 ArrayH::getString(arrayptr, name, 256); // What's the limit on name length?
8416
8417 bool match = (!( strcmp(name.c_str(), guysbuf[GET_REF(npcdataref)].initD_label[init_d_index] )));
8418
8419 ret = ( match ? 10000 : 0 );
8420 break;
8421 }
8422
8423 ///----------------------------------------------------------------------------------------------------//
8424 //Dropset Variables
8425
8426 case DROPSETNULLCHANCE:
8427 {
8428 if(ri->dropsetdataref > MAXITEMDROPSETS)
8429 {
8430 Z_scripterrlog("Invalid dropset pointer %d\n", ri->dropsetdataref);
8431 ret = -10000;
8432 break;
8433 }
8434 ret = item_drop_sets[GET_REF(dropsetdataref)].chance[0] * 10000;
8435 break;
8436 }
8437 case DROPSETCHOOSE:
8438 {
8439
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(ri->dropsetdataref > MAXITEMDROPSETS)
8440 {
8441 Z_scripterrlog("Invalid dropset pointer %d\n", ri->dropsetdataref);
8442 ret = -10000;
8443 break;
8444 }
8445 10 ret = select_dropitem(GET_REF(dropsetdataref)) * 10000;
8446 10 break;
8447 }
8448
8449 ///----------------------------------------------------------------------------------------------------//
8450 //Audio Variables
8451
8452 case AUDIOPAN:
8453 {
8454 ret = FFScript::do_getSFX_pan() * 10000;
8455 break;
8456 }
8457
8458 ///----------------------------------------------------------------------------------------------------//
8459 //Graphics->
8460
8461 case NUMDRAWS:
8462 ret = script_drawing_commands.Count() * 10000;
8463 //ret = FFCore.numscriptdraws * 10000; // This isn't updated until end of frame, making it useless!
8464 break;
8465
8466 case MAXDRAWS:
8467 ret = MAX_SCRIPT_DRAWING_COMMANDS * 10000;
8468 break;
8469
8470 case BITMAPWIDTH:
8471 {
8472
2/4
✓ Branch 0 taken 3453 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3453 times.
3453 if (auto bmp = user_bitmaps.check(GET_REF(bitmapref)); bmp && bmp->u_bmp)
8473 {
8474 3453 ret = bmp->width * 10000;
8475 3453 }
8476 else
8477 {
8478 ret = -10000;
8479 }
8480 3453 break;
8481 }
8482
8483 case BITMAPHEIGHT:
8484 {
8485 if (auto bmp = user_bitmaps.check(GET_REF(bitmapref)); bmp && bmp->u_bmp)
8486 {
8487 ret = bmp->height * 10000;
8488 }
8489 else
8490 {
8491 ret = -10000;
8492 }
8493 break;
8494 }
8495
8496 ///----------------------------------------------------------------------------------------------------//
8497 //Stack->
8498 case STACKSIZE:
8499 {
8500 if(user_stack* st = checkStack(GET_REF(stackref), true))
8501 {
8502 ret = st->size(); //NOT *10000
8503 }
8504 else ret = -10000L;
8505 break;
8506 }
8507 case STACKFULL:
8508 {
8509 if(user_stack* st = checkStack(GET_REF(stackref), true))
8510 {
8511 ret = st->full() ? 10000L : 0L;
8512 }
8513 else ret = -10000L;
8514 break;
8515 }
8516
8517 ///----------------------------------------------------------------------------------------------------//
8518 //Misc./Internal
8519 case REFFFC:
8520
2/2
✓ Branch 0 taken 2523 times.
✓ Branch 1 taken 25922 times.
28445 ret = ZScriptVersion::ffcRefIsSpriteId() ? ri->ffcref : ri->ffcref * 10000;
8521 28445 break;
8522
8523 case REFITEM:
8524 608662 ret = ri->itemref;
8525 608662 break;
8526
8527 case REFITEMDATA:
8528 57964044 ret = ri->itemdataref;
8529 57964044 break;
8530
8531 case REFLWPN:
8532 2054459 ret = ri->lwpnref;
8533 2054459 break;
8534
8535 case REFEWPN:
8536 5970308 ret = ri->ewpnref;
8537 5970308 break;
8538
8539 case REFNPC:
8540 32182962 ret = ri->npcref;
8541 32182962 break;
8542
8543 case REFSPRITE:
8544 2 ret = ri->spriteref;
8545 2 break;
8546
8547 case REFMAPDATA: ret = ri->mapdataref; break;
8548 22 case REFSCREEN: ret = ri->screenref; break;
8549 5774191 case REFCOMBODATA: ret = ri->combodataref; break;
8550 case REFCOMBOTRIGGER: ret = ri->combotriggerref; break;
8551 5603 case REFSPRITEDATA: ret = ri->spritedataref; break;
8552 10 case REFBITMAP: ret = ri->bitmapref; break;
8553 2 case REFNPCDATA: ret = ri->npcdataref; break;
8554
8555
8556 549329 case REFDMAPDATA: ret = ri->dmapdataref; break;
8557 case REFSHOPDATA: ret = ri->shopdataref; break;
8558 54 case REFMSGDATA: ret = ri->msgdataref; break;
8559
8560 10 case REFDROPSETDATA: ret = ri->dropsetdataref; break;
8561 case REFBOTTLETYPE: ret = ri->bottletyperef; break;
8562 case REFBOTTLESHOP: ret = ri->bottleshopref; break;
8563 137831 case REFGENERICDATA: ret = ri->genericdataref; break;
8564 case REFFILE: ret = ri->fileref; break;
8565 case REFDIRECTORY: ret = ri->directoryref; break;
8566 case REFSTACK: ret = ri->stackref; break;
8567 91 case REFSUBSCREENDATA: ret = ri->subscreendataref; break;
8568 case REFSUBSCREENPAGE: ret = ri->subscreenpageref; break;
8569 case REFSUBSCREENWIDG: ret = ri->subscreenwidgref; break;
8570 case REFRNG: ret = ri->rngref; break;
8571 case REFWEBSOCKET: ret = ri->websocketref; break;
8572 734476 case CLASS_THISKEY: ret = ri->thiskey; break;
8573 1156 case CLASS_THISKEY2: ret = ri->thiskey2; break;
8574 case REFPALDATA: ret = ri->paldataref; break;
8575 case REFSAVEMENU: ret = ri->savemenuref; break;
8576
8577
8578 case SP:
8579 ret = ri->sp * 10000;
8580 break;
8581 case SP2:
8582 267249 ret = ri->sp;
8583 267249 break;
8584
8585 case PC:
8586 ret = ri->pc;
8587 break;
8588
8589 case SWITCHKEY:
8590 ret = ri->switchkey;
8591 break;
8592
8593 case SCRIPTRAM:
8594 case GLOBALRAM:
8595 1125668249 ret = ArrayH::getElement(GET_D(rINDEX), GET_D(rINDEX2) / 10000);
8596 1125668249 break;
8597
8598 case SCRIPTRAMD:
8599 case GLOBALRAMD:
8600 ret = ArrayH::getElement(GET_D(rINDEX), 0);
8601 break;
8602
8603 case GDD: // Unused, remove?
8604 ret = read_array(game->global_d, GET_D(rINDEX) / 10000);
8605 break;
8606
8607 ///----------------------------------------------------------------------------------------------------//
8608
8609 case GENDATARUNNING:
8610 {
8611 7555 ret = 0;
8612
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7555 times.
7555 if(user_genscript* scr = checkGenericScr(GET_REF(genericdataref)))
8613 {
8614 7555 ret = scr->doscript() ? 10000L : 0L;
8615 7555 }
8616 7555 break;
8617 }
8618 case GENDATASIZE:
8619 {
8620 ret = 0;
8621 if(user_genscript* scr = checkGenericScr(GET_REF(genericdataref)))
8622 {
8623 ret = scr->dataSize()*10000;
8624 }
8625 break;
8626 }
8627
8628 ///----------------------------------------------------------------------------------------------------//
8629
8630 case PORTALX:
8631 {
8632 ret = -10000;
8633 if(portal* p = checkPortal(GET_REF(portalref)))
8634 ret = p->x.getZLong();
8635 break;
8636 }
8637 case PORTALY:
8638 {
8639 ret = -10000;
8640 if(portal* p = checkPortal(GET_REF(portalref)))
8641 ret = p->y.getZLong();
8642 break;
8643 }
8644 case PORTALDMAP:
8645 {
8646 ret = -10000;
8647 if(portal* p = checkPortal(GET_REF(portalref)))
8648 ret = p->destdmap*10000;
8649 break;
8650 }
8651 case PORTALSCREEN:
8652 {
8653 ret = -10000;
8654 if(portal* p = checkPortal(GET_REF(portalref)))
8655 ret = p->destscr*10000;
8656 break;
8657 }
8658 case PORTALACLK:
8659 {
8660 ret = -10000;
8661 if(portal* p = checkPortal(GET_REF(portalref)))
8662 ret = p->aclk*10000;
8663 break;
8664 }
8665 case PORTALAFRM:
8666 {
8667 ret = -10000;
8668 if(portal* p = checkPortal(GET_REF(portalref)))
8669 ret = p->aframe*10000;
8670 break;
8671 }
8672 case PORTALOTILE:
8673 {
8674 ret = -10000;
8675 if(portal* p = checkPortal(GET_REF(portalref)))
8676 ret = p->o_tile*10000;
8677 break;
8678 }
8679 case PORTALASPD:
8680 {
8681 ret = -10000;
8682 if(portal* p = checkPortal(GET_REF(portalref)))
8683 ret = p->aspd*10000;
8684 break;
8685 }
8686 case PORTALFRAMES:
8687 {
8688 ret = -10000;
8689 if(portal* p = checkPortal(GET_REF(portalref)))
8690 ret = p->frames*10000;
8691 break;
8692 }
8693 case PORTALSAVED:
8694 {
8695 ret = 0;
8696 if(portal* p = checkPortal(GET_REF(portalref)))
8697 ret = p->saved_data;
8698 break;
8699 }
8700 case PORTALCLOSEDIS:
8701 {
8702 ret = 0;
8703 if(portal* p = checkPortal(GET_REF(portalref)))
8704 ret = p->prox_active ? 0 : 10000; //Inverted
8705 break;
8706 }
8707 case REFPORTAL:
8708 {
8709 ret = ri->portalref;
8710 break;
8711 }
8712 case REFSAVPORTAL:
8713 {
8714 ret = ri->savportalref;
8715 break;
8716 }
8717 case PORTALWARPSFX:
8718 {
8719 ret = 0;
8720 if(portal* p = checkPortal(GET_REF(portalref)))
8721 ret = p->wsfx ? 0 : 10000;
8722 break;
8723 }
8724 case PORTALWARPVFX:
8725 {
8726 ret = 0;
8727 if(portal* p = checkPortal(GET_REF(portalref)))
8728 ret = p->weffect ? 0 : 10000;
8729 break;
8730 }
8731 case SAVEDPORTALX:
8732 {
8733 ret = -10000;
8734 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
8735 ret = p->x;
8736 break;
8737 }
8738 case SAVEDPORTALY:
8739 {
8740 ret = -10000;
8741 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
8742 ret = p->y;
8743 break;
8744 }
8745 case SAVEDPORTALSRCDMAP:
8746 {
8747 ret = -10000;
8748 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
8749 ret = p->srcdmap * 10000;
8750 break;
8751 }
8752 case SAVEDPORTALDESTDMAP:
8753 {
8754 ret = -10000;
8755 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
8756 ret = p->destdmap * 10000;
8757 break;
8758 }
8759 case SAVEDPORTALSRCSCREEN:
8760 {
8761 ret = -10000;
8762 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
8763 ret = p->srcscr * 10000;
8764 break;
8765 }
8766 case SAVEDPORTALDSTSCREEN:
8767 {
8768 ret = -10000;
8769 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
8770 ret = p->destscr * 10000;
8771 break;
8772 }
8773 case SAVEDPORTALWARPSFX:
8774 {
8775 ret = -10000;
8776 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
8777 ret = p->sfx * 10000;
8778 break;
8779 }
8780 case SAVEDPORTALWARPVFX:
8781 {
8782 ret = -10000;
8783 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
8784 ret = p->warpfx * 10000;
8785 break;
8786 }
8787 case SAVEDPORTALSPRITE:
8788 {
8789 ret = -10000;
8790 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
8791 ret = p->spr * 10000;
8792 break;
8793 }
8794 case SAVEDPORTALPORTAL:
8795 {
8796 ret = 0;
8797 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
8798 ret = getPortalFromSaved(p);
8799 break;
8800 }
8801 case PORTALCOUNT:
8802 {
8803 ret = portals.Count()*10000;
8804 break;
8805 }
8806 case SAVEDPORTALCOUNT:
8807 {
8808 ret = game->user_portals.size()*10000;
8809 break;
8810 }
8811
8812 case GAMEASUBOPEN:
8813 {
8814 ret = subscreen_open && !map_subscreen_open ? 10000 : 0;
8815 break;
8816 }
8817 case GAMEMSUBOPEN:
8818 {
8819 ret = subscreen_open && map_subscreen_open ? 10000 : 0;
8820 break;
8821 }
8822 case GAMEASUBYOFF:
8823 {
8824 47730 ret = active_sub_yoff*10000;
8825 47730 break;
8826 }
8827 case GAMENUMASUB:
8828 {
8829 ret = subscreens_active.size()*10000;
8830 break;
8831 }
8832 case GAMENUMPSUB:
8833 {
8834 ret = subscreens_passive.size()*10000;
8835 break;
8836 }
8837 case GAMENUMOSUB:
8838 {
8839 ret = subscreens_overlay.size()*10000;
8840 break;
8841 }
8842 case GAMENUMMSUB:
8843 {
8844 ret = subscreens_map.size()*10000;
8845 break;
8846 }
8847
8848 ///----------------------------------------------------------------------------------------------------//
8849
8850 case SUBDATACURPG:
8851 {
8852
2/4
✓ Branch 0 taken 54674 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 54674 times.
54674 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref)))
8853
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 54674 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
109348 if (sub->sub_type == sstACTIVE || sub->sub_type == sstMAP)
8854 54674 ret = 10000*sub->curpage;
8855 54674 break;
8856 }
8857 case SUBDATANUMPG:
8858 {
8859
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref)))
8860 {
8861
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
11 if (sub->sub_type == sstACTIVE || sub->sub_type == sstMAP)
8862 11 ret = 10000*sub->pages.size();
8863 else ret = 10000;
8864 11 }
8865 11 break;
8866 }
8867 case SUBDATATYPE:
8868 {
8869 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref)))
8870 ret = sub->sub_type*10000;
8871 break;
8872 }
8873
8874 ///---- ACTIVE SUBSCREENS ONLY
8875 case SUBDATACURSORPOS:
8876 {
8877 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8878 {
8879 SubscrPage& pg = sub->cur_page();
8880 ret = pg.cursor_pos * 10000;
8881 }
8882 break;
8883 }
8884 case SUBDATASCRIPT:
8885 {
8886 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8887 ret = sub->script * 10000;
8888 break;
8889 }
8890 case SUBDATATRANSLEFTTY:
8891 {
8892 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8893 {
8894 auto& trans = sub->trans_left;
8895 ret = trans.type * 10000;
8896 }
8897 break;
8898 }
8899 case SUBDATATRANSLEFTSFX:
8900 {
8901 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8902 {
8903 auto& trans = sub->trans_left;
8904 ret = trans.tr_sfx * 10000;
8905 }
8906 break;
8907 }
8908 case SUBDATATRANSRIGHTTY:
8909 {
8910 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8911 {
8912 auto& trans = sub->trans_right;
8913 ret = trans.type * 10000;
8914 }
8915 break;
8916 }
8917 case SUBDATATRANSRIGHTSFX:
8918 {
8919 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8920 {
8921 auto& trans = sub->trans_right;
8922 ret = trans.tr_sfx * 10000;
8923 }
8924 break;
8925 }
8926 case SUBDATASELECTORDSTX:
8927 {
8928 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8929 ret = sub->selector_setting.x * 10000;
8930 break;
8931 }
8932 case SUBDATASELECTORDSTY:
8933 {
8934 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8935 ret = sub->selector_setting.y * 10000;
8936 break;
8937 }
8938 case SUBDATASELECTORDSTW:
8939 {
8940 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8941 ret = sub->selector_setting.w * 10000;
8942 break;
8943 }
8944 case SUBDATASELECTORDSTH:
8945 {
8946 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8947 ret = sub->selector_setting.h * 10000;
8948 break;
8949 }
8950 ///---- CURRENTLY OPEN ACTIVE SUBSCREEN ONLY
8951 case SUBDATATRANSCLK:
8952 {
8953 5031 ret = -10000;
8954
3/6
✓ Branch 0 taken 5031 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5031 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 5031 times.
5031 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8955 {
8956
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5031 times.
✓ Branch 2 taken 5031 times.
✗ Branch 3 not taken.
5031 if(sub != CURRENT_ACTIVE_SUBSCREEN)
8957 Z_scripterrlog("'subscreendata->TransClock' is only"
8958 " valid for the current active/map subscreen!\n");
8959
3/4
✓ Branch 0 taken 5031 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4855 times.
✓ Branch 3 taken 176 times.
5031 else if(subscreen_open && subscr_pg_animating)
8960 176 ret = subscr_pg_clk*10000;
8961 5031 }
8962 5031 break;
8963 }
8964 case SUBDATATRANSTY:
8965 {
8966 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8967 {
8968 auto& trans = subscr_pg_transition;
8969 if(sub != CURRENT_ACTIVE_SUBSCREEN)
8970 Z_scripterrlog("'subscreendata->TransType' is only"
8971 " valid for the current active/map subscreen!\n");
8972 else if(subscreen_open)
8973 ret = trans.type*10000;
8974 }
8975 break;
8976 }
8977 case SUBDATATRANSFROMPG:
8978 {
8979 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8980 {
8981 if(sub != CURRENT_ACTIVE_SUBSCREEN)
8982 Z_scripterrlog("'subscreendata->TransFromPage' is only"
8983 " valid for the current active/map subscreen!\n");
8984 else if(subscreen_open)
8985 ret = subscr_pg_from*10000;
8986 }
8987 break;
8988 }
8989 case SUBDATATRANSTOPG:
8990 {
8991 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8992 {
8993 if(sub != CURRENT_ACTIVE_SUBSCREEN)
8994 Z_scripterrlog("'subscreendata->TransToPage' is only"
8995 " valid for the current active/map subscreen!\n");
8996 else if(subscreen_open)
8997 ret = subscr_pg_to*10000;
8998 }
8999 break;
9000 }
9001
9002 ///----------------------------------------------------------------------------------------------------//
9003 case SUBPGINDEX:
9004 {
9005 if(SubscrPage* pg = checkSubPage(GET_REF(subscreenpageref)))
9006 ret = pg->getIndex() * 10000;
9007 break;
9008 }
9009 case SUBPGNUMWIDG:
9010 {
9011
2/4
✓ Branch 0 taken 1005 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1005 times.
1005 if(SubscrPage* pg = checkSubPage(GET_REF(subscreenpageref)))
9012 1005 ret = pg->size() * 10000;
9013 1005 break;
9014 }
9015 case SUBPGSUBDATA:
9016 {
9017 if(SubscrPage* pg = checkSubPage(GET_REF(subscreenpageref)))
9018 {
9019 auto [sub,ty,_pgid,_ind] = from_subref(GET_REF(subscreenpageref));
9020 ret = get_subref(sub,ty,0,0);
9021 }
9022 break;
9023 }
9024 case SUBPGCURSORPOS:
9025 {
9026
2/4
✓ Branch 0 taken 17326 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17326 times.
17326 if(SubscrPage* pg = checkSubPage(GET_REF(subscreenpageref)))
9027 17326 ret = pg->cursor_pos * 10000;
9028 17326 break;
9029 }
9030 ///----------------------------------------------------------------------------------------------------//
9031 ///---- ANY WIDGET TYPE
9032 case SUBWIDGTYPE:
9033 {
9034
2/4
✓ Branch 0 taken 6024 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6024 times.
6024 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9035 6024 ret = 10000*widg->getType();
9036 6024 break;
9037 }
9038 case SUBWIDGINDEX:
9039 {
9040 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9041 {
9042 auto [_sub,_ty,_pgid,ind] = from_subref(GET_REF(subscreenwidgref));
9043 ret = 10000*ind;
9044 }
9045 break;
9046 }
9047 case SUBWIDGDISPITM:
9048 {
9049
2/4
✓ Branch 0 taken 4206 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4206 times.
4206 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9050 {
9051 4206 ret = 10000*widg->getDisplayItem();
9052 4206 }
9053 4206 break;
9054 }
9055 case SUBWIDGEQPITM:
9056 {
9057
2/4
✓ Branch 0 taken 9836 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9836 times.
9836 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9058 {
9059 9836 ret = 10000*widg->getItemVal();
9060 9836 }
9061 9836 break;
9062 }
9063 case SUBWIDGPAGE:
9064 {
9065 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9066 {
9067 auto [sub,ty,pgid,_ind] = from_subref(GET_REF(subscreenwidgref));
9068 ret = get_subref(sub,ty,pgid,0);
9069 }
9070 break;
9071 }
9072 case SUBWIDGPOS:
9073 {
9074 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9075 ret = 10000*widg->pos;
9076 break;
9077 }
9078 case SUBWIDGX:
9079 {
9080
2/4
✓ Branch 0 taken 339 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 339 times.
339 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9081 339 ret = 10000*widg->x;
9082 339 break;
9083 }
9084 case SUBWIDGY:
9085 {
9086
2/4
✓ Branch 0 taken 339 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 339 times.
339 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9087 339 ret = 10000*widg->y;
9088 339 break;
9089 }
9090 case SUBWIDGW:
9091 {
9092 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9093 ret = 10000*widg->w;
9094 break;
9095 }
9096 case SUBWIDGH:
9097 {
9098 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9099 ret = 10000*widg->h;
9100 break;
9101 }
9102 case SUBWIDG_DISPX:
9103 {
9104 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9105 ret = 10000*widg->getX();
9106 break;
9107 }
9108 case SUBWIDG_DISPY:
9109 {
9110 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9111 ret = 10000*widg->getY();
9112 break;
9113 }
9114 case SUBWIDG_DISPW:
9115 {
9116 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9117 ret = 10000*widg->getW();
9118 break;
9119 }
9120 case SUBWIDG_DISPH:
9121 {
9122 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9123 ret = 10000*widg->getH();
9124 break;
9125 }
9126 case SUBWIDGREQCOUNTER:
9127 {
9128 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9129 ret = 10000 * widg->req_counter;
9130 break;
9131 }
9132 case SUBWIDGREQCOUNTERCOND:
9133 {
9134 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9135 ret = 10000 * widg->req_counter_cond_type;
9136 break;
9137 }
9138 case SUBWIDGREQCOUNTERVAL:
9139 {
9140 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9141 ret = 10000 * widg->req_counter_val;
9142 break;
9143 }
9144 case SUBWIDGREQLITEMS:
9145 {
9146 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9147 ret = 10000 * widg->req_litems;
9148 break;
9149 }
9150 case SUBWIDGREQLITEMLEVEL:
9151 {
9152 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9153 ret = 10000 * widg->req_litem_level;
9154 break;
9155 }
9156 case SUBWIDGREQ_LEVEL_STATE_LEVEL:
9157 {
9158 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9159 ret = 10000 * widg->req_lstate_level;
9160 break;
9161 }
9162 case SUBWIDGREQ_SCRSTATE_MAP:
9163 {
9164 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9165 ret = 10000 * widg->req_scrstate_map;
9166 break;
9167 }
9168 case SUBWIDGREQ_SCRSTATE_SCREEN:
9169 {
9170 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9171 ret = 10000 * widg->req_scrstate_scr;
9172 break;
9173 }
9174 case SUBWIDGREQSCRIPTDISABLED:
9175 {
9176 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9177 ret = widg->is_disabled ? 10000 : 0;
9178 break;
9179 }
9180 ///---- ACTIVE SUBSCREENS ONLY
9181 case SUBWIDGSELECTORDSTX:
9182 {
9183 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
9184 ret = 10000*widg->selector_override.x;
9185 break;
9186 }
9187 case SUBWIDGSELECTORDSTY:
9188 {
9189 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
9190 ret = 10000*widg->selector_override.y;
9191 break;
9192 }
9193 case SUBWIDGSELECTORDSTW:
9194 {
9195 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
9196 ret = 10000*widg->selector_override.w;
9197 break;
9198 }
9199 case SUBWIDGSELECTORDSTH:
9200 {
9201 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
9202 ret = 10000*widg->selector_override.h;
9203 break;
9204 }
9205
9206 case SUBWIDGPRESSSCRIPT:
9207 {
9208 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
9209 ret = 10000*widg->generic_script;
9210 break;
9211 }
9212 case SUBWIDGPGMODE:
9213 {
9214 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
9215 ret = 10000*widg->pg_mode;
9216 break;
9217 }
9218 case SUBWIDGPGTARG:
9219 {
9220 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
9221 ret = 10000*widg->pg_targ;
9222 break;
9223 }
9224
9225 case SUBWIDGTRANSPGTY:
9226 {
9227 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
9228 {
9229 auto& trans = widg->pg_trans;
9230 ret = 10000*trans.type;
9231 }
9232 break;
9233 }
9234 case SUBWIDGTRANSPGSFX:
9235 {
9236 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
9237 {
9238 auto& trans = widg->pg_trans;
9239 ret = 10000*trans.tr_sfx;
9240 }
9241 break;
9242 }
9243 ///---- VARYING WIDGET TYPES
9244 case SUBWIDGTY_FONT:
9245 {
9246 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9247 {
9248 auto ty = widg->getType();
9249 switch(ty)
9250 {
9251 case widgTEXT:
9252 ret = 10000*((SW_Text*)widg)->fontid;
9253 break;
9254 case widgITMCOOLDOWNTEXT:
9255 ret = 10000*((SW_ItemCooldownText*)widg)->fontid;
9256 break;
9257 case widgTEXTBOX:
9258 ret = 10000*((SW_TextBox*)widg)->fontid;
9259 break;
9260 case widgSELECTEDTEXT:
9261 ret = 10000*((SW_SelectedText*)widg)->fontid;
9262 break;
9263 case widgTIME:
9264 ret = 10000*((SW_Time*)widg)->fontid;
9265 break;
9266 case widgCOUNTER:
9267 ret = 10000*((SW_Counter*)widg)->fontid;
9268 break;
9269 case widgBTNCOUNTER:
9270 ret = 10000*((SW_BtnCounter*)widg)->fontid;
9271 break;
9272 case widgOLDCTR:
9273 ret = 10000*((SW_Counters*)widg)->fontid;
9274 break;
9275 case widgMMAPTITLE:
9276 ret = 10000*((SW_MMapTitle*)widg)->fontid;
9277 break;
9278 default:
9279 bad_subwidg_type(false, ty);
9280 ret = -10000;
9281 break;
9282 }
9283 }
9284 break;
9285 }
9286 case SUBWIDGTY_ALIGN:
9287 {
9288 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9289 {
9290 auto ty = widg->getType();
9291 switch(ty)
9292 {
9293 case widgTEXT:
9294 ret = 10000*((SW_Text*)widg)->align;
9295 break;
9296 case widgITMCOOLDOWNTEXT:
9297 ret = 10000*((SW_ItemCooldownText*)widg)->align;
9298 break;
9299 case widgTEXTBOX:
9300 ret = 10000*((SW_TextBox*)widg)->align;
9301 break;
9302 case widgSELECTEDTEXT:
9303 ret = 10000*((SW_SelectedText*)widg)->align;
9304 break;
9305 case widgTIME:
9306 ret = 10000*((SW_Time*)widg)->align;
9307 break;
9308 case widgCOUNTER:
9309 ret = 10000*((SW_Counter*)widg)->align;
9310 break;
9311 case widgBTNCOUNTER:
9312 ret = 10000*((SW_BtnCounter*)widg)->align;
9313 break;
9314 case widgMMAPTITLE:
9315 ret = 10000*((SW_MMapTitle*)widg)->align;
9316 break;
9317 default:
9318 bad_subwidg_type(false, ty);
9319 ret = -10000;
9320 break;
9321 }
9322 }
9323 break;
9324 }
9325 case SUBWIDGTY_SHADOWTY:
9326 {
9327 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9328 {
9329 auto ty = widg->getType();
9330 switch(ty)
9331 {
9332 case widgTEXT:
9333 ret = 10000*((SW_Text*)widg)->shadtype;
9334 break;
9335 case widgITMCOOLDOWNTEXT:
9336 ret = 10000*((SW_ItemCooldownText*)widg)->shadtype;
9337 break;
9338 case widgTEXTBOX:
9339 ret = 10000*((SW_TextBox*)widg)->shadtype;
9340 break;
9341 case widgSELECTEDTEXT:
9342 ret = 10000*((SW_SelectedText*)widg)->shadtype;
9343 break;
9344 case widgTIME:
9345 ret = 10000*((SW_Time*)widg)->shadtype;
9346 break;
9347 case widgCOUNTER:
9348 ret = 10000*((SW_Counter*)widg)->shadtype;
9349 break;
9350 case widgBTNCOUNTER:
9351 ret = 10000*((SW_BtnCounter*)widg)->shadtype;
9352 break;
9353 case widgOLDCTR:
9354 ret = 10000*((SW_Counters*)widg)->shadtype;
9355 break;
9356 case widgMMAPTITLE:
9357 ret = 10000*((SW_MMapTitle*)widg)->shadtype;
9358 break;
9359 default:
9360 bad_subwidg_type(false, ty);
9361 ret = -10000;
9362 break;
9363 }
9364 }
9365 break;
9366 }
9367 case SUBWIDGTY_COLOR_TXT:
9368 {
9369 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9370 {
9371 auto ty = widg->getType();
9372 switch(ty)
9373 {
9374 case widgTEXT:
9375 ret = 10000*((SW_Text*)widg)->c_text.get_int_color();
9376 break;
9377 case widgITMCOOLDOWNTEXT:
9378 ret = 10000*((SW_ItemCooldownText*)widg)->c_text.get_int_color();
9379 break;
9380 case widgTEXTBOX:
9381 ret = 10000*((SW_TextBox*)widg)->c_text.get_int_color();
9382 break;
9383 case widgSELECTEDTEXT:
9384 ret = 10000*((SW_SelectedText*)widg)->c_text.get_int_color();
9385 break;
9386 case widgTIME:
9387 ret = 10000*((SW_Time*)widg)->c_text.get_int_color();
9388 break;
9389 case widgCOUNTER:
9390 ret = 10000*((SW_Counter*)widg)->c_text.get_int_color();
9391 break;
9392 case widgBTNCOUNTER:
9393 ret = 10000*((SW_BtnCounter*)widg)->c_text.get_int_color();
9394 break;
9395 case widgOLDCTR:
9396 ret = 10000*((SW_Counters*)widg)->c_text.get_int_color();
9397 break;
9398 case widgMMAPTITLE:
9399 ret = 10000*((SW_MMapTitle*)widg)->c_text.get_int_color();
9400 break;
9401 case widgMCGUFF_FRAME:
9402 ret = 10000*((SW_TriFrame*)widg)->c_number.get_int_color();
9403 break;
9404 default:
9405 bad_subwidg_type(false, ty);
9406 break;
9407 }
9408 }
9409 break;
9410 }
9411 case SUBWIDGTY_COLOR_SHD:
9412 {
9413 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9414 {
9415 auto ty = widg->getType();
9416 switch(ty)
9417 {
9418 case widgTEXT:
9419 ret = 10000*((SW_Text*)widg)->c_shadow.get_int_color();
9420 break;
9421 case widgITMCOOLDOWNTEXT:
9422 ret = 10000*((SW_ItemCooldownText*)widg)->c_shadow.get_int_color();
9423 break;
9424 case widgTEXTBOX:
9425 ret = 10000*((SW_TextBox*)widg)->c_shadow.get_int_color();
9426 break;
9427 case widgSELECTEDTEXT:
9428 ret = 10000*((SW_SelectedText*)widg)->c_shadow.get_int_color();
9429 break;
9430 case widgTIME:
9431 ret = 10000*((SW_Time*)widg)->c_shadow.get_int_color();
9432 break;
9433 case widgCOUNTER:
9434 ret = 10000*((SW_Counter*)widg)->c_shadow.get_int_color();
9435 break;
9436 case widgBTNCOUNTER:
9437 ret = 10000*((SW_BtnCounter*)widg)->c_shadow.get_int_color();
9438 break;
9439 case widgOLDCTR:
9440 ret = 10000*((SW_Counters*)widg)->c_shadow.get_int_color();
9441 break;
9442 case widgMMAPTITLE:
9443 ret = 10000*((SW_MMapTitle*)widg)->c_shadow.get_int_color();
9444 break;
9445 default:
9446 bad_subwidg_type(false, ty);
9447 break;
9448 }
9449 }
9450 break;
9451 }
9452 case SUBWIDGTY_COLOR_BG:
9453 {
9454 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9455 {
9456 auto ty = widg->getType();
9457 switch(ty)
9458 {
9459 case widgTEXT:
9460 ret = 10000*((SW_Text*)widg)->c_bg.get_int_color();
9461 break;
9462 case widgITMCOOLDOWNTEXT:
9463 ret = 10000*((SW_ItemCooldownText*)widg)->c_bg.get_int_color();
9464 break;
9465 case widgTEXTBOX:
9466 ret = 10000*((SW_TextBox*)widg)->c_bg.get_int_color();
9467 break;
9468 case widgSELECTEDTEXT:
9469 ret = 10000*((SW_SelectedText*)widg)->c_bg.get_int_color();
9470 break;
9471 case widgTIME:
9472 ret = 10000*((SW_Time*)widg)->c_bg.get_int_color();
9473 break;
9474 case widgCOUNTER:
9475 ret = 10000*((SW_Counter*)widg)->c_bg.get_int_color();
9476 break;
9477 case widgBTNCOUNTER:
9478 ret = 10000*((SW_BtnCounter*)widg)->c_bg.get_int_color();
9479 break;
9480 case widgOLDCTR:
9481 ret = 10000*((SW_Counters*)widg)->c_bg.get_int_color();
9482 break;
9483 case widgMMAPTITLE:
9484 ret = 10000*((SW_MMapTitle*)widg)->c_bg.get_int_color();
9485 break;
9486 case widgBGCOLOR:
9487 ret = 10000*((SW_Clear*)widg)->c_bg.get_int_color();
9488 break;
9489 case widgCOUNTERPERCBAR:
9490 ret = 10000*((SW_CounterPercentBar*)widg)->c_bg.get_int_color();
9491 break;
9492 default:
9493 bad_subwidg_type(false, ty);
9494 break;
9495 }
9496 }
9497 break;
9498 }
9499
9500 case SUBWIDGTY_COLOR_TXT2:
9501 {
9502 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9503 {
9504 auto ty = widg->getType();
9505 switch(ty)
9506 {
9507 case widgCOUNTER:
9508 ret = 10000*((SW_Counter*)widg)->c_text2.get_int_color();
9509 break;
9510 case widgBTNCOUNTER:
9511 ret = 10000*((SW_BtnCounter*)widg)->c_text2.get_int_color();
9512 break;
9513 default:
9514 bad_subwidg_type(false, ty);
9515 break;
9516 }
9517 }
9518 break;
9519 }
9520 case SUBWIDGTY_COLOR_SHD2:
9521 {
9522 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9523 {
9524 auto ty = widg->getType();
9525 switch(ty)
9526 {
9527 case widgCOUNTER:
9528 ret = 10000*((SW_Counter*)widg)->c_shadow2.get_int_color();
9529 break;
9530 case widgBTNCOUNTER:
9531 ret = 10000*((SW_BtnCounter*)widg)->c_shadow2.get_int_color();
9532 break;
9533 default:
9534 bad_subwidg_type(false, ty);
9535 break;
9536 }
9537 }
9538 break;
9539 }
9540 case SUBWIDGTY_COLOR_BG2:
9541 {
9542 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9543 {
9544 auto ty = widg->getType();
9545 switch(ty)
9546 {
9547 case widgCOUNTER:
9548 ret = 10000*((SW_Counter*)widg)->c_bg2.get_int_color();
9549 break;
9550 case widgBTNCOUNTER:
9551 ret = 10000*((SW_BtnCounter*)widg)->c_bg2.get_int_color();
9552 break;
9553 default:
9554 bad_subwidg_type(false, ty);
9555 break;
9556 }
9557 }
9558 break;
9559 }
9560 case SUBWIDGTY_COLOR_OLINE:
9561 {
9562 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9563 {
9564 auto ty = widg->getType();
9565 switch(ty)
9566 {
9567 case widgLINE:
9568 ret = 10000*((SW_Line*)widg)->c_line.get_int_color();
9569 break;
9570 case widgRECT:
9571 ret = 10000*((SW_Rect*)widg)->c_outline.get_int_color();
9572 break;
9573 case widgMCGUFF_FRAME:
9574 ret = 10000*((SW_TriFrame*)widg)->c_outline.get_int_color();
9575 break;
9576 default:
9577 bad_subwidg_type(false, ty);
9578 break;
9579 }
9580 }
9581 break;
9582 }
9583 case SUBWIDGTY_COLOR_FILL:
9584 {
9585 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9586 {
9587 auto ty = widg->getType();
9588 switch(ty)
9589 {
9590 case widgRECT:
9591 ret = 10000*((SW_Rect*)widg)->c_fill.get_int_color();
9592 break;
9593 case widgCOUNTERPERCBAR:
9594 ret = 10000*((SW_CounterPercentBar*)widg)->c_fill.get_int_color();
9595 break;
9596 default:
9597 bad_subwidg_type(false, ty);
9598 break;
9599 }
9600 }
9601 break;
9602 }
9603 case SUBWIDGTY_BUTTON:
9604 {
9605 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9606 {
9607 auto ty = widg->getType();
9608 switch(ty)
9609 {
9610 case widgBTNITM:
9611 ret = 10000*((SW_ButtonItem*)widg)->btn;
9612 break;
9613 case widgBTNCOUNTER:
9614 ret = 10000*((SW_BtnCounter*)widg)->btn;
9615 break;
9616 case widgITMCOOLDOWNGAUGE:
9617 ret = 10000*((SW_ItemCooldownGauge*)widg)->button_id;
9618 break;
9619 case widgITMCOOLDOWNTEXT:
9620 ret = 10000*((SW_ItemCooldownText*)widg)->button_id;
9621 break;
9622 default:
9623 bad_subwidg_type(false, ty);
9624 ret = -10000;
9625 break;
9626 }
9627 }
9628 break;
9629 }
9630 case SUBWIDGTY_MINDIG:
9631 {
9632 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9633 {
9634 auto ty = widg->getType();
9635 switch(ty)
9636 {
9637 case widgCOUNTER:
9638 ret = 10000*((SW_Counter*)widg)->mindigits;
9639 break;
9640 case widgBTNCOUNTER:
9641 ret = 10000*((SW_BtnCounter*)widg)->mindigits;
9642 break;
9643 case widgOLDCTR:
9644 ret = 10000*((SW_Counters*)widg)->digits;
9645 break;
9646 default:
9647 bad_subwidg_type(false, ty);
9648 ret = -10000;
9649 break;
9650 }
9651 }
9652 break;
9653 }
9654 case SUBWIDGTY_MAXDIG:
9655 {
9656 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9657 {
9658 auto ty = widg->getType();
9659 switch(ty)
9660 {
9661 case widgCOUNTER:
9662 ret = 10000*((SW_Counter*)widg)->maxdigits;
9663 break;
9664 case widgBTNCOUNTER:
9665 ret = 10000*((SW_BtnCounter*)widg)->maxdigits;
9666 break;
9667 default:
9668 bad_subwidg_type(false, ty);
9669 ret = -10000;
9670 break;
9671 }
9672 }
9673 break;
9674 }
9675 case SUBWIDGTY_INFITM:
9676 {
9677 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9678 {
9679 auto ty = widg->getType();
9680 switch(ty)
9681 {
9682 case widgCOUNTER:
9683 ret = 10000*((SW_Counter*)widg)->infitm;
9684 break;
9685 case widgOLDCTR:
9686 ret = 10000*((SW_Counters*)widg)->infitm;
9687 break;
9688 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE:
9689 ret = 10000*((SW_GaugePiece*)widg)->inf_item;
9690 break;
9691 case widgITMCOOLDOWNGAUGE:
9692 default:
9693 bad_subwidg_type(false, ty);
9694 ret = -10000;
9695 break;
9696 }
9697 }
9698 break;
9699 }
9700 case SUBWIDGTY_INFCHAR:
9701 {
9702 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9703 {
9704 auto ty = widg->getType();
9705 switch(ty)
9706 {
9707 case widgCOUNTER:
9708 ret = 10000*byte(((SW_Counter*)widg)->infchar);
9709 break;
9710 case widgOLDCTR:
9711 ret = 10000*byte(((SW_Counters*)widg)->infchar);
9712 break;
9713 case widgBTNCOUNTER:
9714 ret = 10000*byte(((SW_BtnCounter*)widg)->infchar);
9715 break;
9716 default:
9717 bad_subwidg_type(false, ty);
9718 break;
9719 }
9720 }
9721 break;
9722 }
9723 case SUBWIDGTY_COSTIND:
9724 {
9725 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9726 {
9727 auto ty = widg->getType();
9728 switch(ty)
9729 {
9730 case widgBTNCOUNTER:
9731 ret = 10000*((SW_BtnCounter*)widg)->costind;
9732 break;
9733 default:
9734 bad_subwidg_type(false, ty);
9735 ret = -1;
9736 break;
9737 }
9738 }
9739 break;
9740 }
9741 case SUBWIDGTY_COLOR_PLAYER:
9742 {
9743 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9744 {
9745 auto ty = widg->getType();
9746 switch(ty)
9747 {
9748 case widgMMAP:
9749 ret = 10000*((SW_MMap*)widg)->c_plr.get_int_color();
9750 break;
9751 case widgLMAP:
9752 ret = 10000*((SW_LMap*)widg)->c_plr.get_int_color();
9753 break;
9754 default:
9755 bad_subwidg_type(false, ty);
9756 break;
9757 }
9758 }
9759 break;
9760 }
9761 case SUBWIDGTY_COLOR_CMPBLNK:
9762 {
9763 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9764 {
9765 auto ty = widg->getType();
9766 switch(ty)
9767 {
9768 case widgMMAP:
9769 ret = 10000*((SW_MMap*)widg)->c_cmp_blink.get_int_color();
9770 break;
9771 default:
9772 bad_subwidg_type(false, ty);
9773 break;
9774 }
9775 }
9776 break;
9777 }
9778 case SUBWIDGTY_COLOR_CMPOFF:
9779 {
9780 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9781 {
9782 auto ty = widg->getType();
9783 switch(ty)
9784 {
9785 case widgMMAP:
9786 ret = 10000*((SW_MMap*)widg)->c_cmp_off.get_int_color();
9787 break;
9788 default:
9789 bad_subwidg_type(false, ty);
9790 break;
9791 }
9792 }
9793 break;
9794 }
9795 case SUBWIDGTY_COLOR_ROOM:
9796 {
9797 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9798 {
9799 auto ty = widg->getType();
9800 switch(ty)
9801 {
9802 case widgLMAP:
9803 ret = 10000*((SW_LMap*)widg)->c_room.get_int_color();
9804 break;
9805 default:
9806 bad_subwidg_type(false, ty);
9807 break;
9808 }
9809 }
9810 break;
9811 }
9812 case SUBWIDGTY_ITEMCLASS:
9813 {
9814 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9815 {
9816 auto ty = widg->getType();
9817 switch(ty)
9818 {
9819 case widgITEMSLOT:
9820 ret = 10000*((SW_ItemSlot*)widg)->iclass;
9821 break;
9822 case widgITMCOOLDOWNGAUGE:
9823 ret = 10000*((SW_ItemCooldownGauge*)widg)->item_class;
9824 break;
9825 case widgITMCOOLDOWNTEXT:
9826 ret = 10000*((SW_ItemCooldownText*)widg)->item_class;
9827 break;
9828 default:
9829 bad_subwidg_type(false, ty);
9830 break;
9831 }
9832 }
9833 break;
9834 }
9835 case SUBWIDGTY_ITEMID:
9836 {
9837
2/4
✓ Branch 0 taken 1455 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1455 times.
1455 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9838 {
9839 1455 auto ty = widg->getType();
9840
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1455 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1455 switch(ty)
9841 {
9842 case widgITEMSLOT:
9843 1455 ret = 10000*((SW_ItemSlot*)widg)->iid;
9844 1455 break;
9845 case widgITMCOOLDOWNGAUGE:
9846 ret = 10000*((SW_ItemCooldownGauge*)widg)->specific_item_id;
9847 break;
9848 case widgITMCOOLDOWNTEXT:
9849 ret = 10000*((SW_ItemCooldownText*)widg)->specific_item_id;
9850 break;
9851 default:
9852 bad_subwidg_type(false, ty);
9853 break;
9854 }
9855 1455 }
9856 1455 break;
9857 }
9858 case SUBWIDGTY_FRAMETILE:
9859 {
9860 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9861 {
9862 auto ty = widg->getType();
9863 switch(ty)
9864 {
9865 case widgMCGUFF_FRAME:
9866 ret = 10000*((SW_TriFrame*)widg)->frame_tile;
9867 break;
9868 default:
9869 bad_subwidg_type(false, ty);
9870 break;
9871 }
9872 }
9873 break;
9874 }
9875 case SUBWIDGTY_FRAMECSET:
9876 {
9877 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9878 {
9879 auto ty = widg->getType();
9880 switch(ty)
9881 {
9882 case widgMCGUFF_FRAME:
9883 ret = 10000*((SW_TriFrame*)widg)->frame_cset;
9884 break;
9885 default:
9886 bad_subwidg_type(false, ty);
9887 break;
9888 }
9889 }
9890 break;
9891 }
9892 case SUBWIDGTY_PIECETILE:
9893 {
9894 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9895 {
9896 auto ty = widg->getType();
9897 switch(ty)
9898 {
9899 case widgMCGUFF_FRAME:
9900 ret = 10000*((SW_TriFrame*)widg)->piece_tile;
9901 break;
9902 default:
9903 bad_subwidg_type(false, ty);
9904 break;
9905 }
9906 }
9907 break;
9908 }
9909 case SUBWIDGTY_PIECECSET:
9910 {
9911 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9912 {
9913 auto ty = widg->getType();
9914 switch(ty)
9915 {
9916 case widgMCGUFF_FRAME:
9917 ret = 10000*((SW_TriFrame*)widg)->piece_cset;
9918 break;
9919 default:
9920 bad_subwidg_type(false, ty);
9921 break;
9922 }
9923 }
9924 break;
9925 }
9926 case SUBWIDGTY_FLIP:
9927 {
9928 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9929 {
9930 auto ty = widg->getType();
9931 switch(ty)
9932 {
9933 case widgMCGUFF:
9934 ret = 10000*((SW_McGuffin*)widg)->flip;
9935 break;
9936 case widgTILEBLOCK:
9937 ret = 10000*((SW_TileBlock*)widg)->flip;
9938 break;
9939 case widgMINITILE:
9940 ret = 10000*((SW_MiniTile*)widg)->flip;
9941 break;
9942 default:
9943 bad_subwidg_type(false, ty);
9944 break;
9945 }
9946 }
9947 break;
9948 }
9949 case SUBWIDGTY_NUMBER:
9950 {
9951 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9952 {
9953 auto ty = widg->getType();
9954 switch(ty)
9955 {
9956 case widgMCGUFF:
9957 ret = 10000*((SW_McGuffin*)widg)->number;
9958 break;
9959 default:
9960 bad_subwidg_type(false, ty);
9961 break;
9962 }
9963 }
9964 break;
9965 }
9966 case SUBWIDGTY_FRAMES:
9967 {
9968 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9969 {
9970 auto ty = widg->getType();
9971 switch(ty)
9972 {
9973 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
9974 ret = 10000*((SW_GaugePiece*)widg)->frames;
9975 break;
9976 default:
9977 bad_subwidg_type(false, ty);
9978 ret = -10000;
9979 break;
9980 }
9981 }
9982 break;
9983 }
9984 case SUBWIDGTY_SPEED:
9985 {
9986 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9987 {
9988 auto ty = widg->getType();
9989 switch(ty)
9990 {
9991 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
9992 ret = 10000*((SW_GaugePiece*)widg)->speed;
9993 break;
9994 default:
9995 bad_subwidg_type(false, ty);
9996 ret = -10000;
9997 break;
9998 }
9999 }
10000 break;
10001 }
10002 case SUBWIDGTY_DELAY:
10003 {
10004 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10005 {
10006 auto ty = widg->getType();
10007 switch(ty)
10008 {
10009 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
10010 ret = 10000*((SW_GaugePiece*)widg)->delay;
10011 break;
10012 default:
10013 bad_subwidg_type(false, ty);
10014 ret = -10000;
10015 break;
10016 }
10017 }
10018 break;
10019 }
10020 case SUBWIDGTY_CONTAINER:
10021 {
10022 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10023 {
10024 auto ty = widg->getType();
10025 switch(ty)
10026 {
10027 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
10028 ret = 10000*((SW_GaugePiece*)widg)->container;
10029 break;
10030 default:
10031 bad_subwidg_type(false, ty);
10032 ret = -10000;
10033 break;
10034 }
10035 }
10036 break;
10037 }
10038 case SUBWIDGTY_GAUGE_WID:
10039 {
10040 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10041 {
10042 auto ty = widg->getType();
10043 switch(ty)
10044 {
10045 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
10046 ret = 10000*(((SW_GaugePiece*)widg)->gauge_wid+1);
10047 break;
10048 default:
10049 bad_subwidg_type(false, ty);
10050 ret = -10000;
10051 break;
10052 }
10053 }
10054 break;
10055 }
10056 case SUBWIDGTY_GAUGE_HEI:
10057 {
10058 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10059 {
10060 auto ty = widg->getType();
10061 switch(ty)
10062 {
10063 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
10064 ret = 10000*(((SW_GaugePiece*)widg)->gauge_hei+1);
10065 break;
10066 default:
10067 bad_subwidg_type(false, ty);
10068 ret = -10000;
10069 break;
10070 }
10071 }
10072 break;
10073 }
10074 case SUBWIDGTY_UNITS:
10075 {
10076 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10077 {
10078 auto ty = widg->getType();
10079 switch(ty)
10080 {
10081 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
10082 ret = 10000*(((SW_GaugePiece*)widg)->unit_per_frame+1);
10083 break;
10084 default:
10085 bad_subwidg_type(false, ty);
10086 ret = -10000;
10087 break;
10088 }
10089 }
10090 break;
10091 }
10092 case SUBWIDGTY_HSPACE:
10093 {
10094 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10095 {
10096 auto ty = widg->getType();
10097 switch(ty)
10098 {
10099 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
10100 ret = 10000*((SW_GaugePiece*)widg)->hspace;
10101 break;
10102 default:
10103 bad_subwidg_type(false, ty);
10104 ret = -10000;
10105 break;
10106 }
10107 }
10108 break;
10109 }
10110 case SUBWIDGTY_VSPACE:
10111 {
10112 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10113 {
10114 auto ty = widg->getType();
10115 switch(ty)
10116 {
10117 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
10118 ret = 10000*((SW_GaugePiece*)widg)->vspace;
10119 break;
10120 default:
10121 bad_subwidg_type(false, ty);
10122 ret = -10000;
10123 break;
10124 }
10125 }
10126 break;
10127 }
10128 case SUBWIDGTY_GRIDX:
10129 {
10130 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10131 {
10132 auto ty = widg->getType();
10133 switch(ty)
10134 {
10135 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
10136 ret = 10000*((SW_GaugePiece*)widg)->grid_xoff;
10137 break;
10138 default:
10139 bad_subwidg_type(false, ty);
10140 ret = -10000;
10141 break;
10142 }
10143 }
10144 break;
10145 }
10146 case SUBWIDGTY_GRIDY:
10147 {
10148 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10149 {
10150 auto ty = widg->getType();
10151 switch(ty)
10152 {
10153 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
10154 ret = 10000*((SW_GaugePiece*)widg)->grid_yoff;
10155 break;
10156 default:
10157 bad_subwidg_type(false, ty);
10158 ret = -10000;
10159 break;
10160 }
10161 }
10162 break;
10163 }
10164 case SUBWIDGTY_ANIMVAL:
10165 {
10166 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10167 {
10168 auto ty = widg->getType();
10169 switch(ty)
10170 {
10171 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
10172 ret = 10000*((SW_GaugePiece*)widg)->anim_val;
10173 break;
10174 default:
10175 bad_subwidg_type(false, ty);
10176 ret = -10000;
10177 break;
10178 }
10179 }
10180 break;
10181 }
10182 case SUBWIDGTY_SHOWDRAIN:
10183 {
10184 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10185 {
10186 auto ty = widg->getType();
10187 switch(ty)
10188 {
10189 case widgMGAUGE:
10190 ret = 10000*((SW_MagicGaugePiece*)widg)->showdrain;
10191 break;
10192 default:
10193 bad_subwidg_type(false, ty);
10194 ret = -10000;
10195 break;
10196 }
10197 }
10198 break;
10199 }
10200 case SUBWIDGTY_PERCONTAINER:
10201 {
10202 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10203 {
10204 auto ty = widg->getType();
10205 switch(ty)
10206 {
10207 case widgMISCGAUGE:
10208 ret = 10000*((SW_MiscGaugePiece*)widg)->per_container;
10209 break;
10210 case widgITMCOOLDOWNGAUGE:
10211 ret = 10000*((SW_ItemCooldownGauge*)widg)->per_container;
10212 break;
10213 default:
10214 bad_subwidg_type(false, ty);
10215 ret = -10000;
10216 break;
10217 }
10218 }
10219 break;
10220 }
10221 case SUBWIDGTY_TOTAL:
10222 {
10223 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10224 {
10225 auto ty = widg->getType();
10226 switch(ty)
10227 {
10228 case widgITMCOOLDOWNGAUGE:
10229 ret = 10000*((SW_ItemCooldownGauge*)widg)->total_points;
10230 break;
10231 default:
10232 bad_subwidg_type(false, ty);
10233 ret = -10000;
10234 break;
10235 }
10236 }
10237 break;
10238 }
10239 case SUBWIDGTY_TABSIZE:
10240 {
10241 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10242 {
10243 auto ty = widg->getType();
10244 switch(ty)
10245 {
10246 case widgTEXTBOX:
10247 ret = 10000*((SW_TextBox*)widg)->tabsize;
10248 break;
10249 case widgSELECTEDTEXT:
10250 ret = 10000*((SW_SelectedText*)widg)->tabsize;
10251 break;
10252 default:
10253 bad_subwidg_type(false, ty);
10254 ret = -10000;
10255 break;
10256 }
10257 }
10258 break;
10259 }
10260 case SUBWIDGTY_LITEMS:
10261 {
10262 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10263 {
10264 auto ty = widg->getType();
10265 switch(ty)
10266 {
10267 case widgMMAP:
10268 ret = 10000*((SW_MMap*)widg)->compass_litems;
10269 break;
10270 default:
10271 bad_subwidg_type(false, ty);
10272 ret = -10000;
10273 break;
10274 }
10275 }
10276 break;
10277 }
10278
10279 case GETRENDERTARGET:
10280 ret=(zscriptDrawingRenderTarget->GetCurrentRenderTarget())*10000;
10281 break;
10282
10283 default:
10284 {
10285
2/2
✓ Branch 0 taken 461406591 times.
✓ Branch 1 taken 303622041 times.
765028632 if (zasm_array_supports(arg))
10286 {
10287 461406591 int ref_arg = get_register_ref_dependency(arg).value_or(0);
10288 #ifdef DEBUG_REGISTER_DEPS
10289 if (ref_arg) debug_get_ref(ref_arg);
10290 #endif
10291
2/2
✓ Branch 0 taken 273943091 times.
✓ Branch 1 taken 187463500 times.
461406591 int ref = ref_arg ? get_ref(ref_arg) : 0;
10292 461406591 ret = zasm_array_get(arg, ref, GET_D(rINDEX) / 10000);
10293 461406591 }
10294
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 303622041 times.
303622041 else if (auto r = scripting_engine_get_register(arg))
10295 303622041 ret = *r;
10296 765028632 break;
10297 }
10298 }
10299
10300 3241826608 current_zasm_register = 0;
10301
10302 3241826608 return ret;
10303 4569413646 }
10304
10305 //Setter Instructions
10306
10307
10308 2461433812 void set_register(int32_t arg, int32_t value)
10309 {
10310
3/4
✓ Branch 0 taken 2461433812 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1817398673 times.
✓ Branch 3 taken 644035139 times.
2461433812 if (arg >= D(0) && arg <= D(7))
10311 {
10312 644035139 ri->d[arg - D(0)] = value;
10313 644035139 return;
10314 }
10315
4/4
✓ Branch 0 taken 1783346860 times.
✓ Branch 1 taken 34051813 times.
✓ Branch 2 taken 1783314675 times.
✓ Branch 3 taken 32185 times.
1817398673 else if (arg >= GD(0) && arg <= GD(MAX_SCRIPT_REGISTERS))
10316 {
10317 32185 game->global_d[arg-GD(0)] = value;
10318 32185 return;
10319 }
10320
10321 //Macros
10322
10323 #define SET_SPRITEDATA_VAR_INT(member, str) \
10324 { \
10325 if(unsigned(GET_REF(spritedataref)) > (MAXWPNS-1) ) \
10326 { \
10327 Z_scripterrlog("Invalid Sprite ID passed to spritedata->%s: %d\n", str, GET_REF(spritedataref)); \
10328 } \
10329 else \
10330 { \
10331 wpnsbuf[GET_REF(spritedataref)].member = vbound((value / 10000),0,214747); \
10332 } \
10333 } \
10334
10335 #define SET_SPRITEDATA_VAR_BYTE(member, str) \
10336 { \
10337 if(unsigned(GET_REF(spritedataref)) > (MAXWPNS-1) ) \
10338 { \
10339 Z_scripterrlog("Invalid Sprite ID passed to spritedata->%s: %d\n", str, GET_REF(spritedataref)); \
10340 } \
10341 else \
10342 { \
10343 wpnsbuf[GET_REF(spritedataref)].member = vbound((value / 10000),0,255); \
10344 } \
10345 } \
10346
10347 1817366488 current_zasm_register = arg;
10348
10349 // Do not ever use `return` in these cases!
10350
227/988
✗ Branch 0 not taken.
✓ Branch 1 taken 531793831 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 47910073 times.
✓ Branch 4 taken 4515947 times.
✓ Branch 5 taken 13964 times.
✓ Branch 6 taken 2047856 times.
✓ Branch 7 taken 3683 times.
✓ Branch 8 taken 2299966 times.
✓ Branch 9 taken 2299128 times.
✓ Branch 10 taken 13928 times.
✓ Branch 11 taken 14206 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 14336 times.
✓ Branch 14 taken 16044 times.
✓ Branch 15 taken 4153 times.
✓ Branch 16 taken 4155 times.
✓ Branch 17 taken 13890 times.
✓ Branch 18 taken 13913 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 811 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 477697 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 497243 times.
✓ Branch 26 taken 2779 times.
✓ Branch 27 taken 76581 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 97671 times.
✓ Branch 30 taken 2220 times.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✓ Branch 33 taken 283529 times.
✓ Branch 34 taken 14323 times.
✓ Branch 35 taken 62 times.
✓ Branch 36 taken 1 times.
✓ Branch 37 taken 5411 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 48 times.
✓ Branch 40 taken 952 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✓ Branch 44 taken 871 times.
✓ Branch 45 taken 2319 times.
✗ Branch 46 not taken.
✓ Branch 47 taken 718 times.
✓ Branch 48 taken 5878 times.
✓ Branch 49 taken 1 times.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✓ Branch 54 taken 26326 times.
✓ Branch 55 taken 388698 times.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✓ Branch 67 taken 3 times.
✓ Branch 68 taken 277656 times.
✓ Branch 69 taken 878585 times.
✓ Branch 70 taken 96249 times.
✓ Branch 71 taken 96251 times.
✓ Branch 72 taken 96260 times.
✓ Branch 73 taken 96267 times.
✗ Branch 74 not taken.
✗ Branch 75 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✓ Branch 78 taken 475 times.
✓ Branch 79 taken 4859 times.
✓ Branch 80 taken 3652 times.
✓ Branch 81 taken 2578 times.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 90 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✓ Branch 93 taken 4 times.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
✗ Branch 96 not taken.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✗ Branch 99 not taken.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✗ Branch 102 not taken.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 105 not taken.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✗ Branch 108 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
✗ Branch 111 not taken.
✗ Branch 112 not taken.
✓ Branch 113 taken 1135896 times.
✓ Branch 114 taken 745063 times.
✓ Branch 115 taken 299968 times.
✓ Branch 116 taken 296242 times.
✓ Branch 117 taken 282832 times.
✓ Branch 118 taken 282860 times.
✓ Branch 119 taken 187242 times.
✓ Branch 120 taken 120980 times.
✓ Branch 121 taken 119032 times.
✓ Branch 122 taken 119083 times.
✓ Branch 123 taken 262942 times.
✓ Branch 124 taken 262942 times.
✓ Branch 125 taken 262942 times.
✓ Branch 126 taken 262942 times.
✗ Branch 127 not taken.
✗ Branch 128 not taken.
✗ Branch 129 not taken.
✗ Branch 130 not taken.
✓ Branch 131 taken 1135888 times.
✓ Branch 132 taken 745063 times.
✓ Branch 133 taken 261841 times.
✓ Branch 134 taken 261833 times.
✓ Branch 135 taken 261906 times.
✓ Branch 136 taken 261940 times.
✓ Branch 137 taken 177985 times.
✓ Branch 138 taken 112110 times.
✓ Branch 139 taken 115497 times.
✓ Branch 140 taken 115548 times.
✓ Branch 141 taken 262942 times.
✓ Branch 142 taken 262942 times.
✓ Branch 143 taken 262942 times.
✓ Branch 144 taken 262942 times.
✗ Branch 145 not taken.
✗ Branch 146 not taken.
✗ Branch 147 not taken.
✗ Branch 148 not taken.
✗ Branch 149 not taken.
✗ Branch 150 not taken.
✗ Branch 151 not taken.
✗ Branch 152 not taken.
✗ Branch 153 not taken.
✗ Branch 154 not taken.
✗ Branch 155 not taken.
✗ Branch 156 not taken.
✗ Branch 157 not taken.
✗ Branch 158 not taken.
✗ Branch 159 not taken.
✗ Branch 160 not taken.
✗ Branch 161 not taken.
✗ Branch 162 not taken.
✗ Branch 163 not taken.
✓ Branch 164 taken 2 times.
✗ Branch 165 not taken.
✗ Branch 166 not taken.
✗ Branch 167 not taken.
✗ Branch 168 not taken.
✗ Branch 169 not taken.
✗ Branch 170 not taken.
✗ Branch 171 not taken.
✗ Branch 172 not taken.
✗ Branch 173 not taken.
✗ Branch 174 not taken.
✗ Branch 175 not taken.
✗ Branch 176 not taken.
✗ Branch 177 not taken.
✗ Branch 178 not taken.
✗ Branch 179 not taken.
✗ Branch 180 not taken.
✗ Branch 181 not taken.
✗ Branch 182 not taken.
✗ Branch 183 not taken.
✗ Branch 184 not taken.
✗ Branch 185 not taken.
✗ Branch 186 not taken.
✗ Branch 187 not taken.
✗ Branch 188 not taken.
✗ Branch 189 not taken.
✗ Branch 190 not taken.
✗ Branch 191 not taken.
✗ Branch 192 not taken.
✗ Branch 193 not taken.
✗ Branch 194 not taken.
✗ Branch 195 not taken.
✗ Branch 196 not taken.
✗ Branch 197 not taken.
✓ Branch 198 taken 182 times.
✗ Branch 199 not taken.
✗ Branch 200 not taken.
✗ Branch 201 not taken.
✗ Branch 202 not taken.
✗ Branch 203 not taken.
✗ Branch 204 not taken.
✗ Branch 205 not taken.
✗ Branch 206 not taken.
✗ Branch 207 not taken.
✗ Branch 208 not taken.
✗ Branch 209 not taken.
✗ Branch 210 not taken.
✗ Branch 211 not taken.
✗ Branch 212 not taken.
✗ Branch 213 not taken.
✗ Branch 214 not taken.
✓ Branch 215 taken 2760 times.
✗ Branch 216 not taken.
✗ Branch 217 not taken.
✗ Branch 218 not taken.
✗ Branch 219 not taken.
✗ Branch 220 not taken.
✗ Branch 221 not taken.
✗ Branch 222 not taken.
✗ Branch 223 not taken.
✗ Branch 224 not taken.
✗ Branch 225 not taken.
✓ Branch 226 taken 99 times.
✗ Branch 227 not taken.
✓ Branch 228 taken 13 times.
✗ Branch 229 not taken.
✗ Branch 230 not taken.
✗ Branch 231 not taken.
✗ Branch 232 not taken.
✗ Branch 233 not taken.
✓ Branch 234 taken 214057 times.
✓ Branch 235 taken 30 times.
✓ Branch 236 taken 214043 times.
✓ Branch 237 taken 971 times.
✓ Branch 238 taken 408 times.
✗ Branch 239 not taken.
✓ Branch 240 taken 71609 times.
✗ Branch 241 not taken.
✗ Branch 242 not taken.
✓ Branch 243 taken 82238 times.
✓ Branch 244 taken 1939 times.
✗ Branch 245 not taken.
✓ Branch 246 taken 6 times.
✓ Branch 247 taken 6 times.
✓ Branch 248 taken 1441 times.
✗ Branch 249 not taken.
✓ Branch 250 taken 6730 times.
✓ Branch 251 taken 476 times.
✓ Branch 252 taken 148992 times.
✓ Branch 253 taken 154523 times.
✗ Branch 254 not taken.
✓ Branch 255 taken 2464 times.
✓ Branch 256 taken 3263 times.
✗ Branch 257 not taken.
✓ Branch 258 taken 26540 times.
✓ Branch 259 taken 6 times.
✓ Branch 260 taken 429 times.
✓ Branch 261 taken 6 times.
✓ Branch 262 taken 787 times.
✓ Branch 263 taken 6 times.
✓ Branch 264 taken 885 times.
✓ Branch 265 taken 4922 times.
✓ Branch 266 taken 839 times.
✓ Branch 267 taken 2465 times.
✓ Branch 268 taken 6 times.
✓ Branch 269 taken 71310 times.
✓ Branch 270 taken 71308 times.
✓ Branch 271 taken 1768 times.
✓ Branch 272 taken 70954 times.
✗ Branch 273 not taken.
✗ Branch 274 not taken.
✗ Branch 275 not taken.
✓ Branch 276 taken 6 times.
✓ Branch 277 taken 72525 times.
✓ Branch 278 taken 72542 times.
✓ Branch 279 taken 6 times.
✓ Branch 280 taken 833 times.
✓ Branch 281 taken 833 times.
✓ Branch 282 taken 25012 times.
✗ Branch 283 not taken.
✓ Branch 284 taken 42 times.
✓ Branch 285 taken 12 times.
✓ Branch 286 taken 68360 times.
✓ Branch 287 taken 1130 times.
✗ Branch 288 not taken.
✗ Branch 289 not taken.
✗ Branch 290 not taken.
✗ Branch 291 not taken.
✗ Branch 292 not taken.
✗ Branch 293 not taken.
✓ Branch 294 taken 527 times.
✗ Branch 295 not taken.
✗ Branch 296 not taken.
✗ Branch 297 not taken.
✗ Branch 298 not taken.
✓ Branch 299 taken 72192 times.
✗ Branch 300 not taken.
✗ Branch 301 not taken.
✗ Branch 302 not taken.
✗ Branch 303 not taken.
✗ Branch 304 not taken.
✗ Branch 305 not taken.
✗ Branch 306 not taken.
✗ Branch 307 not taken.
✗ Branch 308 not taken.
✓ Branch 309 taken 390184 times.
✓ Branch 310 taken 30 times.
✓ Branch 311 taken 390781 times.
✓ Branch 312 taken 57530 times.
✓ Branch 313 taken 55587 times.
✗ Branch 314 not taken.
✓ Branch 315 taken 227257 times.
✓ Branch 316 taken 117 times.
✗ Branch 317 not taken.
✓ Branch 318 taken 457872 times.
✓ Branch 319 taken 305561 times.
✓ Branch 320 taken 93 times.
✗ Branch 321 not taken.
✗ Branch 322 not taken.
✓ Branch 323 taken 293753 times.
✗ Branch 324 not taken.
✓ Branch 325 taken 7539 times.
✓ Branch 326 taken 12175 times.
✓ Branch 327 taken 305977 times.
✓ Branch 328 taken 398520 times.
✗ Branch 329 not taken.
✓ Branch 330 taken 74446 times.
✓ Branch 331 taken 178 times.
✗ Branch 332 not taken.
✓ Branch 333 taken 35337 times.
✗ Branch 334 not taken.
✓ Branch 335 taken 199 times.
✓ Branch 336 taken 1039 times.
✓ Branch 337 taken 199 times.
✓ Branch 338 taken 549 times.
✓ Branch 339 taken 78832 times.
✓ Branch 340 taken 1104 times.
✓ Branch 341 taken 156969 times.
✓ Branch 342 taken 4552 times.
✗ Branch 343 not taken.
✓ Branch 344 taken 194229 times.
✓ Branch 345 taken 193736 times.
✓ Branch 346 taken 84994 times.
✓ Branch 347 taken 44193 times.
✗ Branch 348 not taken.
✗ Branch 349 not taken.
✗ Branch 350 not taken.
✓ Branch 351 taken 325611 times.
✓ Branch 352 taken 325024 times.
✓ Branch 353 taken 44 times.
✓ Branch 354 taken 202345 times.
✓ Branch 355 taken 202345 times.
✓ Branch 356 taken 37812 times.
✗ Branch 357 not taken.
✗ Branch 358 not taken.
✗ Branch 359 not taken.
✓ Branch 360 taken 5519 times.
✗ Branch 361 not taken.
✗ Branch 362 not taken.
✗ Branch 363 not taken.
✗ Branch 364 not taken.
✗ Branch 365 not taken.
✓ Branch 366 taken 4 times.
✗ Branch 367 not taken.
✓ Branch 368 taken 8364 times.
✗ Branch 369 not taken.
✗ Branch 370 not taken.
✓ Branch 371 taken 91132 times.
✗ Branch 372 not taken.
✗ Branch 373 not taken.
✗ Branch 374 not taken.
✗ Branch 375 not taken.
✗ Branch 376 not taken.
✗ Branch 377 not taken.
✗ Branch 378 not taken.
✗ Branch 379 not taken.
✗ Branch 380 not taken.
✗ Branch 381 not taken.
✓ Branch 382 taken 6 times.
✓ Branch 383 taken 4 times.
✓ Branch 384 taken 360 times.
✓ Branch 385 taken 360 times.
✗ Branch 386 not taken.
✗ Branch 387 not taken.
✗ Branch 388 not taken.
✗ Branch 389 not taken.
✗ Branch 390 not taken.
✗ Branch 391 not taken.
✗ Branch 392 not taken.
✗ Branch 393 not taken.
✗ Branch 394 not taken.
✗ Branch 395 not taken.
✗ Branch 396 not taken.
✗ Branch 397 not taken.
✗ Branch 398 not taken.
✗ Branch 399 not taken.
✗ Branch 400 not taken.
✗ Branch 401 not taken.
✗ Branch 402 not taken.
✗ Branch 403 not taken.
✓ Branch 404 taken 14 times.
✗ Branch 405 not taken.
✗ Branch 406 not taken.
✗ Branch 407 not taken.
✗ Branch 408 not taken.
✗ Branch 409 not taken.
✗ Branch 410 not taken.
✗ Branch 411 not taken.
✗ Branch 412 not taken.
✗ Branch 413 not taken.
✗ Branch 414 not taken.
✗ Branch 415 not taken.
✗ Branch 416 not taken.
✗ Branch 417 not taken.
✗ Branch 418 not taken.
✓ Branch 419 taken 30 times.
✓ Branch 420 taken 30 times.
✗ Branch 421 not taken.
✗ Branch 422 not taken.
✗ Branch 423 not taken.
✗ Branch 424 not taken.
✗ Branch 425 not taken.
✗ Branch 426 not taken.
✗ Branch 427 not taken.
✓ Branch 428 taken 10 times.
✗ Branch 429 not taken.
✗ Branch 430 not taken.
✗ Branch 431 not taken.
✗ Branch 432 not taken.
✗ Branch 433 not taken.
✗ Branch 434 not taken.
✗ Branch 435 not taken.
✗ Branch 436 not taken.
✗ Branch 437 not taken.
✗ Branch 438 not taken.
✗ Branch 439 not taken.
✗ Branch 440 not taken.
✓ Branch 441 taken 27297 times.
✓ Branch 442 taken 537 times.
✗ Branch 443 not taken.
✓ Branch 444 taken 900 times.
✓ Branch 445 taken 7396 times.
✓ Branch 446 taken 6728 times.
✗ Branch 447 not taken.
✓ Branch 448 taken 11 times.
✗ Branch 449 not taken.
✗ Branch 450 not taken.
✗ Branch 451 not taken.
✗ Branch 452 not taken.
✗ Branch 453 not taken.
✓ Branch 454 taken 1853535 times.
✓ Branch 455 taken 606224 times.
✗ Branch 456 not taken.
✗ Branch 457 not taken.
✗ Branch 458 not taken.
✗ Branch 459 not taken.
✗ Branch 460 not taken.
✗ Branch 461 not taken.
✗ Branch 462 not taken.
✓ Branch 463 taken 114 times.
✗ Branch 464 not taken.
✗ Branch 465 not taken.
✗ Branch 466 not taken.
✗ Branch 467 not taken.
✓ Branch 468 taken 370 times.
✗ Branch 469 not taken.
✗ Branch 470 not taken.
✗ Branch 471 not taken.
✗ Branch 472 not taken.
✗ Branch 473 not taken.
✗ Branch 474 not taken.
✗ Branch 475 not taken.
✗ Branch 476 not taken.
✗ Branch 477 not taken.
✗ Branch 478 not taken.
✗ Branch 479 not taken.
✗ Branch 480 not taken.
✗ Branch 481 not taken.
✗ Branch 482 not taken.
✗ Branch 483 not taken.
✗ Branch 484 not taken.
✗ Branch 485 not taken.
✗ Branch 486 not taken.
✗ Branch 487 not taken.
✗ Branch 488 not taken.
✗ Branch 489 not taken.
✗ Branch 490 not taken.
✗ Branch 491 not taken.
✗ Branch 492 not taken.
✗ Branch 493 not taken.
✗ Branch 494 not taken.
✗ Branch 495 not taken.
✗ Branch 496 not taken.
✗ Branch 497 not taken.
✗ Branch 498 not taken.
✗ Branch 499 not taken.
✓ Branch 500 taken 9 times.
✗ Branch 501 not taken.
✗ Branch 502 not taken.
✗ Branch 503 not taken.
✗ Branch 504 not taken.
✗ Branch 505 not taken.
✗ Branch 506 not taken.
✗ Branch 507 not taken.
✗ Branch 508 not taken.
✗ Branch 509 not taken.
✗ Branch 510 not taken.
✗ Branch 511 not taken.
✗ Branch 512 not taken.
✗ Branch 513 not taken.
✗ Branch 514 not taken.
✗ Branch 515 not taken.
✗ Branch 516 not taken.
✗ Branch 517 not taken.
✗ Branch 518 not taken.
✗ Branch 519 not taken.
✓ Branch 520 taken 168468 times.
✗ Branch 521 not taken.
✗ Branch 522 not taken.
✗ Branch 523 not taken.
✗ Branch 524 not taken.
✗ Branch 525 not taken.
✗ Branch 526 not taken.
✗ Branch 527 not taken.
✗ Branch 528 not taken.
✗ Branch 529 not taken.
✓ Branch 530 taken 5120 times.
✗ Branch 531 not taken.
✗ Branch 532 not taken.
✗ Branch 533 not taken.
✗ Branch 534 not taken.
✗ Branch 535 not taken.
✗ Branch 536 not taken.
✗ Branch 537 not taken.
✗ Branch 538 not taken.
✗ Branch 539 not taken.
✗ Branch 540 not taken.
✓ Branch 541 taken 3450 times.
✗ Branch 542 not taken.
✓ Branch 543 taken 42 times.
✗ Branch 544 not taken.
✗ Branch 545 not taken.
✗ Branch 546 not taken.
✗ Branch 547 not taken.
✓ Branch 548 taken 36 times.
✓ Branch 549 taken 36 times.
✗ Branch 550 not taken.
✗ Branch 551 not taken.
✓ Branch 552 taken 36 times.
✗ Branch 553 not taken.
✗ Branch 554 not taken.
✗ Branch 555 not taken.
✗ Branch 556 not taken.
✗ Branch 557 not taken.
✗ Branch 558 not taken.
✗ Branch 559 not taken.
✗ Branch 560 not taken.
✗ Branch 561 not taken.
✗ Branch 562 not taken.
✗ Branch 563 not taken.
✓ Branch 564 taken 9 times.
✗ Branch 565 not taken.
✗ Branch 566 not taken.
✗ Branch 567 not taken.
✗ Branch 568 not taken.
✗ Branch 569 not taken.
✗ Branch 570 not taken.
✗ Branch 571 not taken.
✗ Branch 572 not taken.
✗ Branch 573 not taken.
✗ Branch 574 not taken.
✗ Branch 575 not taken.
✗ Branch 576 not taken.
✗ Branch 577 not taken.
✗ Branch 578 not taken.
✗ Branch 579 not taken.
✗ Branch 580 not taken.
✗ Branch 581 not taken.
✗ Branch 582 not taken.
✗ Branch 583 not taken.
✗ Branch 584 not taken.
✗ Branch 585 not taken.
✗ Branch 586 not taken.
✗ Branch 587 not taken.
✗ Branch 588 not taken.
✗ Branch 589 not taken.
✗ Branch 590 not taken.
✗ Branch 591 not taken.
✗ Branch 592 not taken.
✗ Branch 593 not taken.
✗ Branch 594 not taken.
✗ Branch 595 not taken.
✗ Branch 596 not taken.
✗ Branch 597 not taken.
✗ Branch 598 not taken.
✗ Branch 599 not taken.
✗ Branch 600 not taken.
✗ Branch 601 not taken.
✗ Branch 602 not taken.
✗ Branch 603 not taken.
✗ Branch 604 not taken.
✗ Branch 605 not taken.
✗ Branch 606 not taken.
✗ Branch 607 not taken.
✗ Branch 608 not taken.
✗ Branch 609 not taken.
✗ Branch 610 not taken.
✗ Branch 611 not taken.
✗ Branch 612 not taken.
✗ Branch 613 not taken.
✗ Branch 614 not taken.
✗ Branch 615 not taken.
✗ Branch 616 not taken.
✗ Branch 617 not taken.
✗ Branch 618 not taken.
✗ Branch 619 not taken.
✗ Branch 620 not taken.
✗ Branch 621 not taken.
✗ Branch 622 not taken.
✗ Branch 623 not taken.
✗ Branch 624 not taken.
✗ Branch 625 not taken.
✗ Branch 626 not taken.
✗ Branch 627 not taken.
✗ Branch 628 not taken.
✗ Branch 629 not taken.
✗ Branch 630 not taken.
✗ Branch 631 not taken.
✗ Branch 632 not taken.
✗ Branch 633 not taken.
✗ Branch 634 not taken.
✗ Branch 635 not taken.
✗ Branch 636 not taken.
✗ Branch 637 not taken.
✗ Branch 638 not taken.
✗ Branch 639 not taken.
✗ Branch 640 not taken.
✗ Branch 641 not taken.
✗ Branch 642 not taken.
✗ Branch 643 not taken.
✗ Branch 644 not taken.
✗ Branch 645 not taken.
✗ Branch 646 not taken.
✗ Branch 647 not taken.
✗ Branch 648 not taken.
✗ Branch 649 not taken.
✗ Branch 650 not taken.
✗ Branch 651 not taken.
✗ Branch 652 not taken.
✗ Branch 653 not taken.
✗ Branch 654 not taken.
✗ Branch 655 not taken.
✗ Branch 656 not taken.
✗ Branch 657 not taken.
✗ Branch 658 not taken.
✗ Branch 659 not taken.
✗ Branch 660 not taken.
✗ Branch 661 not taken.
✗ Branch 662 not taken.
✗ Branch 663 not taken.
✗ Branch 664 not taken.
✗ Branch 665 not taken.
✗ Branch 666 not taken.
✗ Branch 667 not taken.
✗ Branch 668 not taken.
✗ Branch 669 not taken.
✗ Branch 670 not taken.
✗ Branch 671 not taken.
✗ Branch 672 not taken.
✗ Branch 673 not taken.
✗ Branch 674 not taken.
✗ Branch 675 not taken.
✗ Branch 676 not taken.
✗ Branch 677 not taken.
✗ Branch 678 not taken.
✗ Branch 679 not taken.
✗ Branch 680 not taken.
✗ Branch 681 not taken.
✗ Branch 682 not taken.
✗ Branch 683 not taken.
✗ Branch 684 not taken.
✗ Branch 685 not taken.
✗ Branch 686 not taken.
✗ Branch 687 not taken.
✗ Branch 688 not taken.
✗ Branch 689 not taken.
✗ Branch 690 not taken.
✗ Branch 691 not taken.
✗ Branch 692 not taken.
✗ Branch 693 not taken.
✗ Branch 694 not taken.
✗ Branch 695 not taken.
✗ Branch 696 not taken.
✗ Branch 697 not taken.
✗ Branch 698 not taken.
✗ Branch 699 not taken.
✗ Branch 700 not taken.
✗ Branch 701 not taken.
✗ Branch 702 not taken.
✗ Branch 703 not taken.
✗ Branch 704 not taken.
✗ Branch 705 not taken.
✗ Branch 706 not taken.
✗ Branch 707 not taken.
✗ Branch 708 not taken.
✗ Branch 709 not taken.
✗ Branch 710 not taken.
✗ Branch 711 not taken.
✗ Branch 712 not taken.
✗ Branch 713 not taken.
✗ Branch 714 not taken.
✗ Branch 715 not taken.
✗ Branch 716 not taken.
✗ Branch 717 not taken.
✗ Branch 718 not taken.
✗ Branch 719 not taken.
✗ Branch 720 not taken.
✗ Branch 721 not taken.
✗ Branch 722 not taken.
✗ Branch 723 not taken.
✗ Branch 724 not taken.
✗ Branch 725 not taken.
✗ Branch 726 not taken.
✗ Branch 727 not taken.
✗ Branch 728 not taken.
✗ Branch 729 not taken.
✗ Branch 730 not taken.
✗ Branch 731 not taken.
✗ Branch 732 not taken.
✗ Branch 733 not taken.
✗ Branch 734 not taken.
✗ Branch 735 not taken.
✗ Branch 736 not taken.
✗ Branch 737 not taken.
✗ Branch 738 not taken.
✗ Branch 739 not taken.
✗ Branch 740 not taken.
✗ Branch 741 not taken.
✗ Branch 742 not taken.
✗ Branch 743 not taken.
✗ Branch 744 not taken.
✗ Branch 745 not taken.
✗ Branch 746 not taken.
✗ Branch 747 not taken.
✗ Branch 748 not taken.
✗ Branch 749 not taken.
✗ Branch 750 not taken.
✗ Branch 751 not taken.
✗ Branch 752 not taken.
✗ Branch 753 not taken.
✗ Branch 754 not taken.
✗ Branch 755 not taken.
✗ Branch 756 not taken.
✗ Branch 757 not taken.
✗ Branch 758 not taken.
✗ Branch 759 not taken.
✗ Branch 760 not taken.
✗ Branch 761 not taken.
✗ Branch 762 not taken.
✗ Branch 763 not taken.
✗ Branch 764 not taken.
✗ Branch 765 not taken.
✗ Branch 766 not taken.
✗ Branch 767 not taken.
✗ Branch 768 not taken.
✗ Branch 769 not taken.
✗ Branch 770 not taken.
✗ Branch 771 not taken.
✗ Branch 772 not taken.
✗ Branch 773 not taken.
✗ Branch 774 not taken.
✗ Branch 775 not taken.
✗ Branch 776 not taken.
✗ Branch 777 not taken.
✗ Branch 778 not taken.
✗ Branch 779 not taken.
✗ Branch 780 not taken.
✗ Branch 781 not taken.
✗ Branch 782 not taken.
✗ Branch 783 not taken.
✗ Branch 784 not taken.
✗ Branch 785 not taken.
✗ Branch 786 not taken.
✗ Branch 787 not taken.
✗ Branch 788 not taken.
✗ Branch 789 not taken.
✗ Branch 790 not taken.
✗ Branch 791 not taken.
✗ Branch 792 not taken.
✗ Branch 793 not taken.
✗ Branch 794 not taken.
✗ Branch 795 not taken.
✗ Branch 796 not taken.
✗ Branch 797 not taken.
✗ Branch 798 not taken.
✗ Branch 799 not taken.
✗ Branch 800 not taken.
✗ Branch 801 not taken.
✗ Branch 802 not taken.
✗ Branch 803 not taken.
✗ Branch 804 not taken.
✗ Branch 805 not taken.
✗ Branch 806 not taken.
✗ Branch 807 not taken.
✗ Branch 808 not taken.
✗ Branch 809 not taken.
✗ Branch 810 not taken.
✗ Branch 811 not taken.
✗ Branch 812 not taken.
✗ Branch 813 not taken.
✗ Branch 814 not taken.
✗ Branch 815 not taken.
✗ Branch 816 not taken.
✗ Branch 817 not taken.
✗ Branch 818 not taken.
✗ Branch 819 not taken.
✗ Branch 820 not taken.
✗ Branch 821 not taken.
✗ Branch 822 not taken.
✗ Branch 823 not taken.
✗ Branch 824 not taken.
✗ Branch 825 not taken.
✗ Branch 826 not taken.
✗ Branch 827 not taken.
✗ Branch 828 not taken.
✓ Branch 829 taken 646378123 times.
✓ Branch 830 taken 2240371 times.
✓ Branch 831 taken 59236618 times.
✓ Branch 832 taken 12785291 times.
✓ Branch 833 taken 48396679 times.
✓ Branch 834 taken 169200085 times.
✓ Branch 835 taken 109290683 times.
✓ Branch 836 taken 132051524 times.
✗ Branch 837 not taken.
✓ Branch 838 taken 12299117 times.
✗ Branch 839 not taken.
✓ Branch 840 taken 22412 times.
✓ Branch 841 taken 412757 times.
✓ Branch 842 taken 2 times.
✓ Branch 843 taken 979359 times.
✗ Branch 844 not taken.
✓ Branch 845 taken 220 times.
✓ Branch 846 taken 10 times.
✗ Branch 847 not taken.
✗ Branch 848 not taken.
✓ Branch 849 taken 10426780 times.
✓ Branch 850 taken 284 times.
✗ Branch 851 not taken.
✗ Branch 852 not taken.
✓ Branch 853 taken 109743 times.
✓ Branch 854 taken 20806 times.
✓ Branch 855 taken 103742 times.
✓ Branch 856 taken 521996 times.
✗ Branch 857 not taken.
✓ Branch 858 taken 193072 times.
✓ Branch 859 taken 1156 times.
✓ Branch 860 taken 7263 times.
✗ Branch 861 not taken.
✓ Branch 862 taken 139 times.
✓ Branch 863 taken 67 times.
✗ Branch 864 not taken.
✗ Branch 865 not taken.
✗ Branch 866 not taken.
✗ Branch 867 not taken.
✗ Branch 868 not taken.
✗ Branch 869 not taken.
✗ Branch 870 not taken.
✗ Branch 871 not taken.
✗ Branch 872 not taken.
✗ Branch 873 not taken.
✗ Branch 874 not taken.
✗ Branch 875 not taken.
✗ Branch 876 not taken.
✗ Branch 877 not taken.
✗ Branch 878 not taken.
✗ Branch 879 not taken.
✗ Branch 880 not taken.
✗ Branch 881 not taken.
✗ Branch 882 not taken.
✗ Branch 883 not taken.
✗ Branch 884 not taken.
✗ Branch 885 not taken.
✗ Branch 886 not taken.
✗ Branch 887 not taken.
✗ Branch 888 not taken.
✗ Branch 889 not taken.
✗ Branch 890 not taken.
✗ Branch 891 not taken.
✗ Branch 892 not taken.
✓ Branch 893 taken 3 times.
✗ Branch 894 not taken.
✗ Branch 895 not taken.
✗ Branch 896 not taken.
✗ Branch 897 not taken.
✗ Branch 898 not taken.
✗ Branch 899 not taken.
✗ Branch 900 not taken.
✗ Branch 901 not taken.
✗ Branch 902 not taken.
✗ Branch 903 not taken.
✗ Branch 904 not taken.
✗ Branch 905 not taken.
✓ Branch 906 taken 11 times.
✓ Branch 907 taken 11 times.
✓ Branch 908 taken 11 times.
✓ Branch 909 taken 11 times.
✗ Branch 910 not taken.
✗ Branch 911 not taken.
✗ Branch 912 not taken.
✗ Branch 913 not taken.
✗ Branch 914 not taken.
✗ Branch 915 not taken.
✗ Branch 916 not taken.
✗ Branch 917 not taken.
✗ Branch 918 not taken.
✗ Branch 919 not taken.
✓ Branch 920 taken 132 times.
✓ Branch 921 taken 4247 times.
✗ Branch 922 not taken.
✗ Branch 923 not taken.
✗ Branch 924 not taken.
✗ Branch 925 not taken.
✗ Branch 926 not taken.
✗ Branch 927 not taken.
✗ Branch 928 not taken.
✗ Branch 929 not taken.
✗ Branch 930 not taken.
✗ Branch 931 not taken.
✗ Branch 932 not taken.
✗ Branch 933 not taken.
✗ Branch 934 not taken.
✗ Branch 935 not taken.
✗ Branch 936 not taken.
✗ Branch 937 not taken.
✗ Branch 938 not taken.
✗ Branch 939 not taken.
✗ Branch 940 not taken.
✗ Branch 941 not taken.
✗ Branch 942 not taken.
✗ Branch 943 not taken.
✗ Branch 944 not taken.
✗ Branch 945 not taken.
✗ Branch 946 not taken.
✗ Branch 947 not taken.
✗ Branch 948 not taken.
✗ Branch 949 not taken.
✗ Branch 950 not taken.
✗ Branch 951 not taken.
✗ Branch 952 not taken.
✗ Branch 953 not taken.
✗ Branch 954 not taken.
✗ Branch 955 not taken.
✗ Branch 956 not taken.
✗ Branch 957 not taken.
✗ Branch 958 not taken.
✗ Branch 959 not taken.
✗ Branch 960 not taken.
✗ Branch 961 not taken.
✗ Branch 962 not taken.
✗ Branch 963 not taken.
✗ Branch 964 not taken.
✗ Branch 965 not taken.
✗ Branch 966 not taken.
✗ Branch 967 not taken.
✗ Branch 968 not taken.
✗ Branch 969 not taken.
✗ Branch 970 not taken.
✗ Branch 971 not taken.
✗ Branch 972 not taken.
✗ Branch 973 not taken.
✗ Branch 974 not taken.
✗ Branch 975 not taken.
✗ Branch 976 not taken.
✗ Branch 977 not taken.
✗ Branch 978 not taken.
✗ Branch 979 not taken.
✗ Branch 980 not taken.
✗ Branch 981 not taken.
✗ Branch 982 not taken.
✗ Branch 983 not taken.
✗ Branch 984 not taken.
✗ Branch 985 not taken.
✗ Branch 986 not taken.
✗ Branch 987 not taken.
1817366488 switch(arg)
10351 {
10352 ///----------------------------------------------------------------------------------------------------//
10353 //FFC Variables
10354 case DATA:
10355
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4515947 times.
4515947 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10356 {
10357 4515947 zc_ffc_set(*ffc, vbound(value/10000,0,MAXCOMBOS-1));
10358 4515947 }
10359 4515947 break;
10360
10361 case FFSCRIPT:
10362
1/2
✓ Branch 0 taken 13964 times.
✗ Branch 1 not taken.
13964 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10363 {
10364 13964 ffc->script = vbound(value/10000, 0, NUMSCRIPTFFC-1);
10365
2/2
✓ Branch 0 taken 223424 times.
✓ Branch 1 taken 13964 times.
237388 for(int32_t i=0; i<16; i++)
10366 223424 ffc->miscellaneous[i] = 0;
10367
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13964 times.
13964 if (get_qr(qr_CLEARINITDONSCRIPTCHANGE))
10368 {
10369
2/2
✓ Branch 0 taken 111712 times.
✓ Branch 1 taken 13964 times.
125676 for(int32_t i=0; i<8; i++)
10370 111712 ffc->initd[i] = 0;
10371 13964 }
10372 13964 on_reassign_script_engine_data(ScriptType::FFC, ffc->index);
10373 13964 }
10374 13964 break;
10375
10376
10377 case FCSET:
10378
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2047856 times.
2047856 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10379 2047856 ffc->cset = (value/10000)&15;
10380 2047856 break;
10381
10382 case DELAY:
10383
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3683 times.
3683 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10384 3683 ffc->delay = value/10000;
10385 3683 break;
10386
10387 case FX:
10388
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2299966 times.
2299966 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10389 2299966 ffc->x = zslongToFix(value);
10390 2299966 break;
10391
10392 case FY:
10393
1/2
✓ Branch 0 taken 2299128 times.
✗ Branch 1 not taken.
2299128 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10394 2299128 ffc->y=zslongToFix(value);
10395 2299128 break;
10396
10397 case XD:
10398
1/2
✓ Branch 0 taken 13928 times.
✗ Branch 1 not taken.
13928 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10399 13928 ffc->vx=zslongToFix(value);
10400 13928 break;
10401
10402 case YD:
10403
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14206 times.
14206 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10404 14206 ffc->vy=zslongToFix(value);
10405 14206 break;
10406
10407 case FFCID:
10408 break;
10409
10410 case XD2:
10411
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14336 times.
14336 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10412 14336 ffc->ax=zslongToFix(value);
10413 14336 break;
10414
10415 case YD2:
10416
1/2
✓ Branch 0 taken 16044 times.
✗ Branch 1 not taken.
16044 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10417 16044 ffc->ay=zslongToFix(value);
10418 16044 break;
10419
10420 case FFCWIDTH:
10421
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4153 times.
4153 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10422 4153 ffc->hit_width = (value/10000);
10423 4153 break;
10424
10425 case FFCHEIGHT:
10426
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4155 times.
4155 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10427 4155 ffc->hit_height = (value/10000);
10428 4155 break;
10429
10430 case FFTWIDTH:
10431
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13890 times.
13890 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10432 13890 ffc->txsz = vbound(value/10000, 1, 4);
10433 13890 break;
10434
10435 case FFTHEIGHT:
10436
1/2
✓ Branch 0 taken 13913 times.
✗ Branch 1 not taken.
13913 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10437 13913 ffc->tysz = vbound(value/10000, 1, 4);
10438 13913 break;
10439
10440 case FFCLAYER:
10441 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10442 ffc->layer = vbound(value/10000, 0, 7);
10443 break;
10444
10445 case FFLINK:
10446
1/2
✓ Branch 0 taken 811 times.
✗ Branch 1 not taken.
811 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10447 811 (ffc->link)=vbound(value/10000, 0, MAXFFCS-1); // Allow "ffc->Link = 0" to unlink ffc.
10448 //0 is none, setting this before made it impssible to clear it. -Z
10449 811 break;
10450
10451 case FFCLASTCHANGERX:
10452 if (auto ffc = ResolveFFC(GET_REF(ffcref)) )
10453 ffc->changer_x=vbound(zslongToFix(value).getInt(),-32768, 32767);
10454 break;
10455
10456 case FFCLASTCHANGERY:
10457 if (auto ffc = ResolveFFC(GET_REF(ffcref)) )
10458 ffc->changer_y=vbound(zslongToFix(value).getInt(),-32768, 32767);
10459 break;
10460
10461
10462
10463 ///----------------------------------------------------------------------------------------------------//
10464 //Hero's Variables
10465 case LINKX:
10466 {
10467
2/2
✓ Branch 0 taken 23258 times.
✓ Branch 1 taken 454439 times.
477697 if ( get_qr(qr_SPRITEXY_IS_FLOAT) )
10468 {
10469 23258 Hero.setXfix(zslongToFix(value));
10470 23258 }
10471 else
10472 {
10473 454439 Hero.setX(value/10000);
10474 }
10475 }
10476 477697 break;
10477
10478 case LINKCSET:
10479 {
10480 Hero.cs = value/10000;
10481 break;
10482 }
10483 case LINKY:
10484 {
10485
2/2
✓ Branch 0 taken 22483 times.
✓ Branch 1 taken 474760 times.
497243 if ( get_qr(qr_SPRITEXY_IS_FLOAT) )
10486 {
10487 22483 Hero.setYfix(zslongToFix(value));
10488 22483 }
10489 else
10490 {
10491 474760 Hero.setY(value/10000);
10492 }
10493 }
10494 497243 break;
10495
10496 case LINKZ:
10497 {
10498
2/2
✓ Branch 0 taken 2775 times.
✓ Branch 1 taken 4 times.
2779 if ( get_qr(qr_SPRITEXY_IS_FLOAT) )
10499 {
10500 2775 Hero.setZfix(zslongToFix(value));
10501 2775 }
10502 else
10503 {
10504 4 Hero.setZ(value/10000);
10505 }
10506 }
10507 2779 break;
10508
10509 case LINKJUMP:
10510 76581 Hero.setJump(zslongToFix(value));
10511 76581 break;
10512
10513 case HEROFAKEJUMP:
10514 Hero.setFakeFall(zslongToFix(value) * -100);
10515 break;
10516
10517 case LINKDIR:
10518 {
10519 //Hero->setDir() calls reset_hookshot(), which removes the sword sprite.. O_o
10520
3/4
✓ Branch 0 taken 95485 times.
✓ Branch 1 taken 2186 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 95485 times.
97671 if(Hero.getAction() == attacking || Hero.getAction() == sideswimattacking) Hero.dir = (value/10000);
10521 95485 else Hero.setDir(value/10000);
10522
10523 97671 break;
10524 }
10525
10526 case LINKHITDIR:
10527 2220 Hero.setHitDir(value / 10000);
10528 2220 break;
10529
10530 case LINKGRAVITY:
10531 if(value)
10532 Hero.moveflags |= move_obeys_grav;
10533 else
10534 Hero.moveflags &= ~move_obeys_grav;
10535 break;
10536
10537 case HERONOSTEPFORWARD:
10538 FFCore.nostepforward = ( (value) ? 1 : 0 );
10539 break;
10540
10541 case LINKHP:
10542
6/6
✓ Branch 0 taken 177824 times.
✓ Branch 1 taken 105705 times.
✓ Branch 2 taken 283358 times.
✓ Branch 3 taken 171 times.
✓ Branch 4 taken 177653 times.
✓ Branch 5 taken 105705 times.
283529 game->set_life(zc_max(0, zc_min(value/10000,game->get_maxlife())));
10543 283529 break;
10544
10545 case LINKMP:
10546
6/6
✓ Branch 0 taken 6606 times.
✓ Branch 1 taken 7717 times.
✓ Branch 2 taken 14302 times.
✓ Branch 3 taken 21 times.
✓ Branch 4 taken 6585 times.
✓ Branch 5 taken 7717 times.
14323 game->set_magic(zc_max(0, zc_min(value/10000,game->get_maxmagic())));
10547 14323 break;
10548
10549 case LINKMAXHP:
10550 62 game->set_maxlife(value/10000);
10551 62 break;
10552
10553 case LINKMAXMP:
10554 1 game->set_maxmagic(value/10000);
10555 1 break;
10556
10557 case LINKACTION:
10558 {
10559 5411 int32_t act = value / 10000;
10560
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5411 times.
5411 switch(act)
10561 {
10562 case hookshotout:
10563 case stunned:
10564 case ispushing:
10565 FFCore.setHeroAction(act);
10566 break;
10567 default:
10568 5411 Hero.setAction((actiontype)(act));
10569 5411 }
10570 //Protect from writing illegal actions to Hero's raw variable.
10571 //in the future, we can move all scripted actions that are not possible
10572 //to set in ZC into this mechanic. -Z
10573 5411 break;
10574 }
10575
10576 case HEROHEALTHBEEP:
10577 {
10578 int32_t beep = vbound((value/10000),-4, 255);
10579 //-2 suspends system control of stopping the sound
10580 //-3 suspends system control of stopping the sound AND suspends
10581 // system control over starting or playing it.
10582 heart_beep_timer = beep;
10583 if ( heart_beep_timer > -1 )
10584 {
10585 cont_sfx(QMisc.miscsfx[sfxLOWHEART]);
10586 }
10587 else
10588 {
10589 stop_sfx(QMisc.miscsfx[sfxLOWHEART]);
10590 }
10591 break;
10592 }
10593
10594 case LINKHELD:
10595 48 Hero.setHeldItem(vbound(value/10000,0,MAXITEMS-1));
10596 48 break;
10597
10598 case HEROSTEPRATE:
10599
1/2
✓ Branch 0 taken 952 times.
✗ Branch 1 not taken.
952 if(!get_qr(qr_NEW_HERO_MOVEMENT))
10600 {
10601 Z_scripterrlog("To use '%s', you must %s the quest rule '%s'.", "Hero->Step", "enable", "New Hero Movement");
10602 }
10603
1/2
✓ Branch 0 taken 952 times.
✗ Branch 1 not taken.
952 Hero.setStepRate(zc_max(value/10000,0));
10604
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 952 times.
952 if(!get_qr(qr_SCRIPT_WRITING_HEROSTEP_DOESNT_CARRY_OVER))
10605 952 zinit.heroStep = Hero.getStepRate();
10606 952 break;
10607 case HEROSHOVEOFFSET:
10608 if(!get_qr(qr_NEW_HERO_MOVEMENT2))
10609 Z_scripterrlog("To use 'Hero->ShoveOffset', you must enable the quest rule 'Newer Hero Movement'.");
10610 Hero.shove_offset = vbound(zslongToFix(value),16_zf,0_zf);
10611 if(!get_qr(qr_SCRIPT_WRITING_HEROSTEP_DOESNT_CARRY_OVER))
10612 zinit.shove_offset = Hero.shove_offset;
10613 break;
10614
10615 case LINKEQUIP:
10616 {
10617 if ( FFCore.getQuestHeaderInfo(vZelda) == 0x250 && FFCore.getQuestHeaderInfo(vBuild) < 33 )
10618 {
10619 break;
10620 }
10621 //int32_t seta = (value/10000) >> 8; int32_t setb = value/10000) & 0xFF;
10622 int32_t setb = ((value/10000)&0xFF00)>>8, seta = (value/10000)&0xFF;
10623 seta = vbound(seta,-1,255);
10624 setb = vbound(setb,-1,255);
10625
10626 Awpn = seta;
10627 game->awpn = 255;
10628 game->forced_awpn = seta;
10629 game->items_off[seta] = 0;
10630 directItemA = seta;
10631
10632 Bwpn = setb;
10633 game->bwpn = 255;
10634 game->forced_bwpn = setb;
10635 game->items_off[setb] = 0;
10636 directItemB = setb;
10637 break;
10638 }
10639
10640
10641 case SETITEMSLOT:
10642 {
10643 //value = third arg
10644 //int32_t item, int32_t slot, int32_t force
10645 int32_t itm = GET_D(rINDEX)/10000;
10646 itm = vbound(itm, -1, 255);
10647
10648 int32_t slot = GET_D(rINDEX2)/10000;
10649 int32_t force = GET_D(rEXP1)/10000;
10650
10651 //If we add more item buttons, slot should be an int32_t
10652 //and force shuld be an int32_t
10653
10654 /*
10655 For zScript,
10656 const int32_t ITM_REQUIRE_NONE = 0
10657 const int32_t ITM_REQUIRE_INVENTORY = 1
10658 const int32_t ITM_REQUIRE_A_SLOT_RULE = 2
10659 //Combine as flags
10660 */
10661 if ( force == 0 )
10662 {
10663 switch(slot)
10664 {
10665 case 0: //b
10666 Bwpn = itm;
10667 game->items_off[itm] = 0;
10668 game->bwpn = 255;
10669 game->forced_bwpn = itm;
10670 directItemB = itm;
10671 break;
10672
10673 case 1: //a
10674 Awpn = itm;
10675 game->items_off[itm] = 0;
10676 game->awpn = 255;
10677 game->forced_awpn = itm;
10678 directItemA = itm;
10679 break;
10680
10681 case 2: //x
10682 Xwpn = itm;
10683 game->items_off[itm] = 0;
10684 game->xwpn = 255;
10685 game->forced_xwpn = itm;
10686 directItemX = itm;
10687 break;
10688
10689 case 3: //y
10690 Ywpn = itm;
10691 game->items_off[itm] = 0;
10692 game->ywpn = 255;
10693 game->forced_ywpn = itm;
10694 directItemX = itm;
10695 break;
10696 }
10697 }
10698 else if ( force == 1 )
10699 {
10700 if (game->item[itm])
10701 {
10702 switch(slot)
10703 {
10704 case 0: //b
10705 Bwpn = itm;
10706 game->items_off[itm] = 0;
10707 game->bwpn = 255;
10708 game->forced_bwpn = itm;
10709 directItemB = itm;
10710 break;
10711
10712 case 1: //a
10713 Awpn = itm;
10714 game->items_off[itm] = 0;
10715 game->awpn = 255;
10716 game->forced_awpn = itm;
10717 directItemA = itm;
10718 break;
10719
10720 case 2: //x
10721 Xwpn = itm;
10722 game->items_off[itm] = 0;
10723 game->xwpn = 255;
10724 game->forced_xwpn = itm;
10725 directItemX = itm;
10726 break;
10727
10728 case 3: //y
10729 Ywpn = itm;
10730 game->items_off[itm] = 0;
10731 game->ywpn = 255;
10732 game->forced_ywpn = itm;
10733 directItemY = itm;
10734 break;
10735 }
10736 }
10737 }
10738 else if ( force == 2 )
10739 {
10740 switch(slot)
10741 {
10742 case 0: //b
10743 Bwpn = itm;
10744 game->items_off[itm] = 0;
10745 game->bwpn = 255;
10746 game->forced_bwpn = itm;
10747 directItemB = itm;
10748 break;
10749
10750 case 1: //a
10751 if (get_qr(qr_SELECTAWPN))
10752 {
10753 Awpn = itm;
10754 game->items_off[itm] = 0;
10755 game->awpn = 255;
10756 game->forced_awpn = itm;
10757 directItemA = itm;
10758 }
10759 break;
10760
10761 case 2: //x
10762 Xwpn = itm;
10763 game->items_off[itm] = 0;
10764 game->xwpn = 255;
10765 game->forced_xwpn = itm;
10766 directItemX = itm;
10767 break;
10768
10769 case 3: //y
10770 Ywpn = itm;
10771 game->items_off[itm] = 0;
10772 game->ywpn = 255;
10773 game->forced_ywpn = itm;
10774 directItemY = itm;
10775 break;
10776 }
10777 }
10778 else if ( force == 3 ) //Flag ITM_REQUIRE_INVENTORY + ITM_REQUIRE_SLOT_A_RULE
10779 {
10780 if ( game->item[itm] )
10781 {
10782 switch(slot)
10783 {
10784 case 0: //b
10785 Bwpn = itm;
10786 game->items_off[itm] = 0;
10787 game->bwpn = 255;
10788 game->forced_bwpn = itm;
10789 directItemB = itm;
10790 break;
10791
10792 case 1: //a
10793 if (get_qr(qr_SELECTAWPN))
10794 {
10795 Awpn = itm;
10796 game->items_off[itm] = 0;
10797 game->awpn = 255;
10798 game->forced_awpn = itm;
10799 directItemA = itm;
10800 }
10801 break;
10802
10803 case 2: //x
10804 Xwpn = itm;
10805 game->items_off[itm] = 0;
10806 game->xwpn = 255;
10807 game->forced_xwpn = itm;
10808 directItemX = itm;
10809 break;
10810
10811 case 3: //y
10812 Ywpn = itm;
10813 game->items_off[itm] = 0;
10814 game->ywpn = 255;
10815 game->forced_ywpn = itm;
10816 directItemY = itm;
10817 break;
10818 }
10819 }
10820 }
10821 }
10822 break;
10823
10824 case LINKINVIS:
10825 871 Hero.setDontDraw((value ? 2 : 0));
10826 871 break;
10827
10828 case LINKINVINC:
10829 2319 Hero.scriptcoldet=(value/10000);
10830 2319 break;
10831
10832 case LINKENGINEANIMATE:
10833 Hero.do_animation=value;
10834 break;
10835
10836 case LINKSWORDJINX:
10837 718 Hero.setSwordClk(value/10000);
10838 718 break;
10839
10840 case LINKITEMJINX:
10841 5878 Hero.setItemClk(value/10000);
10842 5878 break;
10843
10844 case LINKDRUNK:
10845 1 Hero.setDrunkClock(value/10000);
10846 1 break;
10847
10848 case LINKHXOFS:
10849 (Hero.hxofs)=(zfix)(value/10000);
10850 break;
10851
10852 case LINKROTATION:
10853 if ( get_qr(qr_OLDSPRITEDRAWS) )
10854 {
10855 scripting_log_error_with_context("To use this you must disable the quest rule 'Old (Faster) Sprite Drawing'.");
10856 break;
10857 }
10858 (Hero.rotation)=(value/10000);
10859 break;
10860
10861 case LINKSCALE:
10862 {
10863 if ( get_qr(qr_OLDSPRITEDRAWS) )
10864 {
10865 scripting_log_error_with_context("To use this you must disable the quest rule 'Old (Faster) Sprite Drawing'.");
10866 break;
10867 }
10868 (Hero.scale)=(value/100.0);
10869 break;
10870 }
10871
10872 case LINKHYOFS:
10873 (Hero.hyofs)=(zfix)(value/10000);
10874 break;
10875
10876 case LINKXOFS:
10877 26326 (Hero.xofs)=(zfix)(value/10000);
10878 26326 break;
10879
10880 case LINKYOFS:
10881
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 388698 times.
388698 (Hero.yofs)=(zfix)(value/10000)+(get_qr(qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
10882 388698 break;
10883 case HEROTOTALDYOFFS:
10884 break; //READ-ONLY
10885
10886 case HEROSHADOWXOFS:
10887 (Hero.shadowxofs)=(zfix)(value/10000);
10888 break;
10889
10890 case HEROSHADOWYOFS:
10891 (Hero.shadowyofs)=(zfix)(value/10000);
10892 break;
10893
10894 case LINKZOFS:
10895 (Hero.zofs)=(zfix)(value/10000);
10896 break;
10897
10898 case LINKHXSZ:
10899 (Hero.hit_width)=(zfix)(value/10000);
10900 break;
10901
10902 case LINKHYSZ:
10903 (Hero.hit_height)=(zfix)(value/10000);
10904 break;
10905
10906 case LINKHZSZ:
10907 (Hero.hzsz)=(zfix)(value/10000);
10908 break;
10909
10910 case LINKTXSZ:
10911 (Hero.txsz)=(zfix)(value/10000);
10912 break;
10913
10914 case LINKTYSZ:
10915 (Hero.tysz)=(zfix)(value/10000);
10916 break;
10917
10918 case LINKTILE:
10919 (Hero.tile)=(zfix)(value/10000);
10920 break;
10921
10922 case LINKFLIP:
10923 (Hero.flip)=(zfix)(value/10000);
10924 break;
10925
10926
10927
10928 case LINKINVFRAME:
10929 3 Hero.setHClk( (int32_t)vbound((value/10000), 0, 214747) );
10930 3 break;
10931
10932 case LINKCANFLICKER:
10933 277656 Hero.setCanFlicker((value/10000)?1:0);
10934 277656 break;
10935
10936 case LINKHURTSFX:
10937 878585 Hero.setHurtSFX( (int32_t)vbound((value/10000), 0, 255) );
10938 878585 break;
10939
10940
10941 case LINKITEMB:
10942 {
10943
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96249 times.
96249 if ( value/10000 < -1 )
10944 {
10945 al_trace("Tried to write an invalid item ID to Hero->ItemB: %d\n",value/10000);
10946 break;
10947 }
10948
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96249 times.
96249 if ( value/10000 > MAXITEMS-1 )
10949 {
10950 al_trace("Tried to write an invalid item ID to Hero->ItemB: %d\n",value/10000);
10951 break;
10952 }
10953 //Hero->setBButtonItem(vbound((value/10000),0,(MAXITEMS-1)));
10954
10955
2/2
✓ Branch 0 taken 96237 times.
✓ Branch 1 taken 12 times.
96249 if (Bwpn != (value/10000))
10956 {
10957 12 Bwpn = value/10000;
10958
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if(new_subscreen_active)
10959 12 new_subscreen_active->get_page_pos(Bwpn, game->bwpn);
10960 12 game->forced_bwpn = value/10000;
10961 12 game->items_off[value/10000] = 0;
10962 12 }
10963 96249 directItemB = value/10000;
10964 96249 break;
10965 }
10966
10967
10968 case LINKITEMA:
10969 {
10970
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96251 times.
96251 if ( value/10000 < -1 )
10971 {
10972 Z_scripterrlog("Tried to write an invalid item ID to Hero->ItemA: %d\n",value/10000);
10973 break;
10974 }
10975
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96251 times.
96251 if ( value/10000 > MAXITEMS-1 )
10976 {
10977 Z_scripterrlog("Tried to write an invalid item ID to Hero->ItemA: %d\n",value/10000);
10978 break;
10979 }
10980 //Hero->setBButtonItem(vbound((value/10000),0,(MAXITEMS-1)));
10981
2/2
✓ Branch 0 taken 96240 times.
✓ Branch 1 taken 11 times.
96251 if (Awpn != (value/10000))
10982 {
10983 11 Awpn = value/10000;
10984
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if(new_subscreen_active)
10985 11 new_subscreen_active->get_page_pos(Awpn, game->awpn);
10986 11 game->items_off[value/10000] = 0;
10987 11 game->forced_awpn = value/10000;
10988 11 }
10989 96251 directItemA = value/10000;
10990 96251 break;
10991 }
10992
10993 case LINKITEMX:
10994 {
10995
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96260 times.
96260 if ( value/10000 < -1 )
10996 {
10997 Z_scripterrlog("Tried to write an invalid item ID to Hero->ItemX: %d\n",value/10000);
10998 break;
10999 }
11000
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96260 times.
96260 if ( value/10000 > MAXITEMS-1 )
11001 {
11002 Z_scripterrlog("Tried to write an invalid item ID to Hero->ItemX: %d\n",value/10000);
11003 break;
11004 }
11005 //Hero->setBButtonItem(vbound((value/10000),0,(MAXITEMS-1)));
11006
2/2
✓ Branch 0 taken 96226 times.
✓ Branch 1 taken 34 times.
96260 if (Xwpn != (value/10000))
11007 {
11008 34 Xwpn = value/10000;
11009
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
34 if(new_subscreen_active)
11010 34 new_subscreen_active->get_page_pos(Xwpn, game->xwpn);
11011 34 game->items_off[value/10000] = 0;
11012 34 game->forced_xwpn = value/10000;
11013 34 }
11014 96260 directItemX = value/10000;
11015 96260 break;
11016 }
11017 case LINKITEMY:
11018 {
11019
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96267 times.
96267 if ( value/10000 < -1 )
11020 {
11021 Z_scripterrlog("Tried to write an invalid item ID to Hero->ItemY: %d\n",value/10000);
11022 break;
11023 }
11024
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96267 times.
96267 if ( value/10000 > MAXITEMS-1 )
11025 {
11026 Z_scripterrlog("Tried to write an invalid item ID to Hero->ItemY: %d\n",value/10000);
11027 break;
11028 }
11029 //Hero->setBButtonItem(vbound((value/10000),0,(MAXITEMS-1)));
11030
2/2
✓ Branch 0 taken 96222 times.
✓ Branch 1 taken 45 times.
96267 if (Ywpn != (value/10000))
11031 {
11032 45 Ywpn = value/10000;
11033
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
45 if(new_subscreen_active)
11034 45 new_subscreen_active->get_page_pos(Ywpn, game->ywpn);
11035 45 game->items_off[value/10000] = 0;
11036 45 game->forced_ywpn = value/10000;
11037 45 }
11038 96267 directItemY = value/10000;
11039 96267 break;
11040 }
11041
11042
11043 case LINKEATEN:
11044 Hero.setEaten(value/10000);
11045 break;
11046 case LINKGRABBED:
11047 Hero.inwallm = value != 0;
11048 break;
11049 case HEROBUNNY:
11050 Hero.setBunnyClock(value/10000);
11051 break;
11052 case LINKPUSH:
11053 Hero.pushing = zc_max((value/10000),0);
11054 break;
11055 case LINKSTUN:
11056 475 Hero.setStunClock(value/10000);
11057 475 break;
11058 case LINKSCRIPTTILE:
11059 4859 script_hero_sprite=vbound((value/10000), -1, NEWMAXTILES-1);
11060 4859 break;
11061
11062 case HEROSCRIPTCSET:
11063 3652 script_hero_cset=vbound((value/10000), -1, 0xF);
11064 3652 break;
11065 case LINKSCRIPFLIP:
11066 2578 script_hero_flip=vbound((value/10000),-1,256);
11067 2578 break;
11068
11069 //Set Hero Diagonal
11070 case LINKDIAG:
11071 Hero.setDiagMove(value?1:0);
11072 set_qr(qr_LTTPWALK, value?1:0);
11073 break;
11074
11075 //Set Hero Big Hitbox
11076 case LINKBIGHITBOX:
11077 Hero.setBigHitbox((value/10000)?1:0);
11078 set_qr(qr_LTTPCOLLISION, (value/10000)?1:0);
11079 break;
11080
11081 case LINKCLIMBING:
11082 Hero.setOnSideviewLadder(value!=0?true:false);
11083 break;
11084
11085 case HEROJUMPCOUNT:
11086 Hero.extra_jump_count = value/10000;
11087 break;
11088
11089 case HEROPULLCLK:
11090 Hero.pit_pullclk = value/10000;
11091 break;
11092 case HEROFALLCLK:
11093 {
11094 int32_t val = vbound(value/10000,0,70);
11095 if(val)
11096 Hero.setAction(falling);
11097 else if(Hero.action == falling)
11098 {
11099 Hero.setAction(none);
11100 }
11101 Hero.fallclk = val;
11102 break;
11103 }
11104 case HEROFALLCMB:
11105 Hero.fallCombo = vbound(value/10000,0,MAXCOMBOS-1);
11106 break;
11107 case HERODROWNCLK:
11108 {
11109 int32_t val = vbound(value/10000,0,70);
11110 if(val)
11111 {
11112 if (Hero.action != lavadrowning) Hero.setAction(drowning);
11113 }
11114 else if(Hero.action == drowning || Hero.action == lavadrowning)
11115 {
11116 Hero.setAction(none);
11117 }
11118 Hero.drownclk = val;
11119 break;
11120 }
11121 case HERODROWNCMB:
11122 Hero.drownCombo = vbound(value/10000,0,MAXCOMBOS-1);
11123 break;
11124 case HEROFAKEZ:
11125 {
11126 if ( get_qr(qr_SPRITEXY_IS_FLOAT) )
11127 {
11128 Hero.setFakeZfix(zslongToFix(value));
11129 }
11130 else
11131 {
11132 Hero.setFakeZ(value/10000);
11133 }
11134 }
11135 break;
11136
11137 case HEROSHIELDJINX:
11138 {
11139 Hero.shieldjinxclk = value / 10000;
11140 break;
11141 }
11142
11143 case CLOCKACTIVE:
11144 {
11145 4 Hero.setClock(watch=(value?true:false));
11146 4 break;
11147 }
11148
11149 case CLOCKCLK:
11150 clockclk = vbound((value/10000), 0, 214748);
11151 break;
11152
11153 case HERORESPAWNX:
11154 {
11155 zfix zx = zslongToFix(value);
11156 Hero.respawn_x = vbound(zx, 0_zf, 240_zf);
11157 break;
11158 }
11159
11160 case HERORESPAWNY:
11161 {
11162 zfix zy = zslongToFix(value);
11163 Hero.respawn_y = vbound(zy, 0_zf, 160_zf);
11164 break;
11165 }
11166
11167 case HERORESPAWNDMAP:
11168 {
11169 Hero.respawn_dmap = vbound(value/10000, 0, MAXDMAPS-1);
11170 break;
11171 }
11172
11173 case HERORESPAWNSCR:
11174 {
11175 Hero.respawn_scr = vbound(value/10000, 0, 0x7F);
11176 break;
11177 }
11178
11179
11180 case HEROSWITCHMAXTIMER:
11181 case HEROSWITCHTIMER:
11182 break; //read-only
11183
11184 case HEROIMMORTAL:
11185 {
11186 Hero.setImmortal(value/10000);
11187 break;
11188 }
11189
11190 case HEROCOYOTETIME:
11191 {
11192 auto v = value/10000;
11193 if(v < 0 || v > 65535) v = 65535;
11194 Hero.coyotetime = word(v);
11195 break;
11196 }
11197 case HEROLIFTEDWPN:
11198 {
11199 if(Hero.lift_wpn)
11200 {
11201 delete Hero.lift_wpn;
11202 Hero.lift_wpn = nullptr;
11203 }
11204 if(value)
11205 {
11206 if(weapon* wpn = checkLWpn(value))
11207 {
11208 if(wpn == Hero.lift_wpn) break;
11209 Hero.lift_wpn = wpn;
11210 if(Lwpns.find(wpn) > -1)
11211 Lwpns.remove(wpn);
11212 if(curScriptType == ScriptType::Lwpn && value == curScriptIndex)
11213 earlyretval = RUNSCRIPT_SELFREMOVE;
11214 }
11215 }
11216 break;
11217 }
11218 case HEROLIFTTIMER:
11219 {
11220 Hero.liftclk = value/10000;
11221 break;
11222 }
11223 case HEROLIFTMAXTIMER:
11224 {
11225 Hero.tliftclk = value/10000;
11226 break;
11227 }
11228 case HEROLIFTHEIGHT:
11229 {
11230 Hero.liftheight = zslongToFix(value);
11231 break;
11232 }
11233 case HEROHAMMERSTATE:
11234 {
11235 //readonly
11236 break;
11237 }
11238 case HEROFLICKERCOLOR:
11239 {
11240 Hero.flickercolor = value/10000;
11241 break;
11242 }
11243 case HEROFLICKERTRANSP:
11244 {
11245 Hero.flickertransp = value / 10000;
11246 break;
11247 }
11248 case HEROSCRICECMB:
11249 Hero.script_ice_combo = vbound(value/10000,-1,MAXCOMBOS); break;
11250 case HEROICEVX:
11251 Hero.ice_vx = zslongToFix(value); break;
11252 case HEROICEVY:
11253 Hero.ice_vy = zslongToFix(value); break;
11254 case HEROICEENTRYFRAMES:
11255 Hero.ice_entry_count = vbound(value/10000,0,255); break;
11256 case HEROICEENTRYMAXFRAMES:
11257 Hero.ice_entry_mcount = vbound(value/10000,0,255); break;
11258
11259
11260 ///----------------------------------------------------------------------------------------------------//
11261 //Input States
11262 case INPUTSTART:
11263 {
11264 1135896 control_state[6]=(value?true:false);
11265
2/2
✓ Branch 0 taken 1058724 times.
✓ Branch 1 taken 77172 times.
1135896 if ( get_qr(qr_FIXDRUNKINPUTS) ) drunk_toggle_state[6]=false;
11266 1135896 break;
11267 }
11268
11269 case INPUTMAP:
11270 {
11271 745063 control_state[9]=(value?true:false);
11272
2/2
✓ Branch 0 taken 476961 times.
✓ Branch 1 taken 268102 times.
745063 if ( get_qr(qr_FIXDRUNKINPUTS) )
11273 268102 drunk_toggle_state[9]=false;
11274 745063 break;
11275 }
11276
11277 case INPUTUP:
11278 {
11279 299968 control_state[0]=(value?true:false);
11280
2/2
✓ Branch 0 taken 293445 times.
✓ Branch 1 taken 6523 times.
299968 if ( get_qr(qr_FIXDRUNKINPUTS) ) drunk_toggle_state[0]=false;
11281 299968 break;
11282 }
11283
11284 case INPUTDOWN:
11285 {
11286 296242 control_state[1]=(value?true:false);
11287
2/2
✓ Branch 0 taken 290748 times.
✓ Branch 1 taken 5494 times.
296242 if ( get_qr(qr_FIXDRUNKINPUTS) )
11288 5494 drunk_toggle_state[1]=false;
11289 296242 break;
11290 }
11291
11292 case INPUTLEFT:
11293 {
11294 282832 control_state[2]=(value?true:false);
11295
2/2
✓ Branch 0 taken 277104 times.
✓ Branch 1 taken 5728 times.
282832 if ( get_qr(qr_FIXDRUNKINPUTS) ) drunk_toggle_state[2]=false;
11296 282832 break;
11297 }
11298
11299 case INPUTRIGHT:
11300 {
11301 282860 control_state[3]=(value?true:false);
11302
2/2
✓ Branch 0 taken 277163 times.
✓ Branch 1 taken 5697 times.
282860 if ( get_qr(qr_FIXDRUNKINPUTS) ) drunk_toggle_state[3]=false;
11303 282860 break;
11304 }
11305
11306 case INPUTA:
11307 {
11308 187242 control_state[4]=(value?true:false);
11309
2/2
✓ Branch 0 taken 142947 times.
✓ Branch 1 taken 44295 times.
187242 if ( get_qr(qr_FIXDRUNKINPUTS) ) drunk_toggle_state[4]=false;
11310 187242 break;
11311 }
11312
11313 case INPUTB:
11314 {
11315 120980 control_state[5]=(value?true:false);
11316
2/2
✓ Branch 0 taken 116814 times.
✓ Branch 1 taken 4166 times.
120980 if ( get_qr(qr_FIXDRUNKINPUTS) ) drunk_toggle_state[5]=false;
11317 120980 break;
11318 }
11319
11320 case INPUTL:
11321 {
11322 119032 control_state[7]=(value?true:false);
11323
2/2
✓ Branch 0 taken 116528 times.
✓ Branch 1 taken 2504 times.
119032 if ( get_qr(qr_FIXDRUNKINPUTS) ) drunk_toggle_state[7]=false;
11324 119032 break;
11325 }
11326
11327 case INPUTR:
11328 {
11329 119083 control_state[8]=(value?true:false);
11330
2/2
✓ Branch 0 taken 116579 times.
✓ Branch 1 taken 2504 times.
119083 if ( get_qr(qr_FIXDRUNKINPUTS) ) drunk_toggle_state[8]=false;
11331 119083 break;
11332 }
11333
11334 case INPUTEX1:
11335 {
11336 262942 control_state[10]=(value?true:false);
11337 262942 break;
11338 }
11339
11340 case INPUTEX2:
11341 262942 control_state[11]=(value?true:false);
11342 262942 break;
11343
11344 case INPUTEX3:
11345 262942 control_state[12]=(value?true:false);
11346 262942 break;
11347
11348 case INPUTEX4:
11349 262942 control_state[13]=(value?true:false);
11350 262942 break;
11351
11352 case INPUTAXISUP:
11353 control_state[14]=(value?true:false);
11354 break;
11355
11356 case INPUTAXISDOWN:
11357 control_state[15]=(value?true:false);
11358 break;
11359
11360 case INPUTAXISLEFT:
11361 control_state[16]=(value?true:false);
11362 break;
11363
11364 case INPUTAXISRIGHT:
11365 control_state[17]=(value?true:false);
11366 break;
11367
11368 case INPUTPRESSSTART:
11369 1135888 button_press[6]=(value?true:false);
11370 1135888 break;
11371
11372 case INPUTPRESSMAP:
11373 745063 button_press[9]=(value?true:false);
11374 745063 break;
11375
11376 case INPUTPRESSUP:
11377 261841 button_press[0]=(value?true:false);
11378 261841 break;
11379
11380 case INPUTPRESSDOWN:
11381 261833 button_press[1]=(value?true:false);
11382 261833 break;
11383
11384 case INPUTPRESSLEFT:
11385 261906 button_press[2]=(value?true:false);
11386 261906 break;
11387
11388 case INPUTPRESSRIGHT:
11389 261940 button_press[3]=(value?true:false);
11390 261940 break;
11391
11392 case INPUTPRESSA:
11393 177985 button_press[4]=(value?true:false);
11394 177985 break;
11395
11396 case INPUTPRESSB:
11397 112110 button_press[5]=(value?true:false);
11398 112110 break;
11399
11400 case INPUTPRESSL:
11401 115497 button_press[7]=(value?true:false);
11402 115497 break;
11403
11404 case INPUTPRESSR:
11405 115548 button_press[8]=(value?true:false);
11406 115548 break;
11407
11408 case INPUTPRESSEX1:
11409 262942 button_press[10]=(value?true:false);
11410 262942 break;
11411
11412 case INPUTPRESSEX2:
11413 262942 button_press[11]=(value?true:false);
11414 262942 break;
11415
11416 case INPUTPRESSEX3:
11417 262942 button_press[12]=(value?true:false);
11418 262942 break;
11419
11420 case INPUTPRESSEX4:
11421 262942 button_press[13]=(value?true:false);
11422 262942 break;
11423
11424 case PRESSAXISUP:
11425 button_press[14]=(value?true:false);
11426 break;
11427
11428 case PRESSAXISDOWN:
11429 button_press[15]=(value?true:false);
11430 break;
11431
11432 case PRESSAXISLEFT:
11433 button_press[16]=(value?true:false);
11434 break;
11435
11436 case PRESSAXISRIGHT:
11437 button_press[17]=(value?true:false);
11438 break;
11439
11440 case INPUTMOUSEX:
11441 {
11442 auto [x, y] = rti_game.local_to_world(value/10000, mouse_y);
11443 position_mouse(x, y);
11444 break;
11445 }
11446
11447 case INPUTMOUSEY:
11448 {
11449 int32_t mousequakeoffset = 56+((int32_t)(zc::math::Sin((double)(quakeclk*int64_t(2)-frame))*4));
11450 int32_t tempoffset = (quakeclk > 0) ? mousequakeoffset : (get_qr(qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
11451 auto [x, y] = rti_game.local_to_world(mouse_x, value/10000 + tempoffset);
11452 position_mouse(x, y);
11453 break;
11454 }
11455
11456 case INPUTMOUSEZ:
11457 position_mouse_z(value/10000);
11458 break;
11459
11460 case SIMULATEKEYPRESS:
11461 {
11462 //if ( !keypressed() ) break; //Don;t return values set by setting Hero->Input/Press
11463 //hmm...no, this won;t return properly for modifier keys.
11464 int32_t keyid = GET_D(rINDEX)/10000;
11465 //key = vbound(key,0,n);
11466 if (value/10000) simulate_keypress(keyid << 8);
11467 }
11468 break;
11469
11470 case KEYMODIFIERS:
11471 {
11472 key_shifts = ( value/10000 );
11473 break;
11474 }
11475 break;
11476
11477 ///----------------------------------------------------------------------------------------------------//
11478 //Itemdata Variables
11479 //not mine, but let;s guard some of them all the same -Z
11480 //item class
11481 case IDATATYPE:
11482 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11483 {
11484 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11485 break;
11486 }
11487 (itemsbuf[GET_REF(itemdataref)].type)=vbound(value/10000,0, 254);
11488 flushItemCache();
11489 break;
11490
11491 case IDATAUSEWPN:
11492 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11493 {
11494 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11495 break;
11496 }
11497 (itemsbuf[GET_REF(itemdataref)].weap_data.imitate_weapon)=vbound(value/10000, 0, 255);
11498 break;
11499 case IDATAUSEDEF:
11500 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11501 {
11502 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11503 break;
11504 }
11505 (itemsbuf[GET_REF(itemdataref)].weap_data.default_defense)=vbound(value/10000, 0, 255);
11506 break;
11507 case IDATAWRANGE:
11508 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11509 {
11510 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11511 break;
11512 }
11513 (itemsbuf[GET_REF(itemdataref)].weaprange)=vbound(value/10000, 0, 255);
11514 break;
11515 case IDATAMAGICTIMER:
11516 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11517 {
11518 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11519 break;
11520 }
11521 (itemsbuf[GET_REF(itemdataref)].magiccosttimer[0])=vbound(value/10000, 0, 214747);
11522 break;
11523 case IDATAMAGICTIMER2:
11524 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11525 {
11526 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11527 break;
11528 }
11529 (itemsbuf[GET_REF(itemdataref)].magiccosttimer[1])=vbound(value/10000, 0, 214747);
11530 break;
11531 case IDATADURATION:
11532 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11533 {
11534 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11535 break;
11536 }
11537 (itemsbuf[GET_REF(itemdataref)].weapduration)=vbound(value/10000, 0, 255);
11538 break;
11539
11540 case IDATADUPLICATES:
11541 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11542 {
11543 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11544 break;
11545 }
11546 (itemsbuf[GET_REF(itemdataref)].duplicates)=vbound(value/10000, 0, 255);
11547 break;
11548 case IDATADRAWLAYER:
11549 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11550 {
11551 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11552 break;
11553 }
11554 (itemsbuf[GET_REF(itemdataref)].drawlayer)=vbound(value/10000, 0, 7);
11555 break;
11556 case IDATACOLLECTFLAGS:
11557 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11558 {
11559 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11560 break;
11561 }
11562 //int32_t a = GET_D(rINDEX) / 10000;
11563 (itemsbuf[GET_REF(itemdataref)].collectflags)=vbound(value/10000, 0, 214747);
11564 break;
11565 case IDATAWEAPONSCRIPT:
11566
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11567 {
11568 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11569 break;
11570 }
11571 2 (itemsbuf[GET_REF(itemdataref)].weap_data.script)=vbound(value/10000, 0, 255);
11572 2 break;
11573 case IDATAWEAPHXOFS:
11574 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11575 {
11576 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11577 break;
11578 }
11579 (itemsbuf[GET_REF(itemdataref)].weap_data.hxofs)=(value/10000);
11580 break;
11581 case IDATAWEAPHYOFS:
11582 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11583 {
11584 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11585 break;
11586 }
11587 (itemsbuf[GET_REF(itemdataref)].weap_data.hyofs)=(value/10000);
11588 break;
11589 case IDATAWEAPHXSZ:
11590 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11591 {
11592 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11593 break;
11594 }
11595 (itemsbuf[GET_REF(itemdataref)].weap_data.hxsz)=(value/10000);
11596 break;
11597 case IDATAWEAPHYSZ:
11598 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11599 {
11600 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11601 break;
11602 }
11603 (itemsbuf[GET_REF(itemdataref)].weap_data.hysz)=(value/10000);
11604 break;
11605 case IDATAWEAPHZSZ:
11606 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11607 {
11608 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11609 break;
11610 }
11611 (itemsbuf[GET_REF(itemdataref)].weap_data.hzsz)=(value/10000);
11612 break;
11613 case IDATAWEAPXOFS:
11614 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11615 {
11616 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11617 break;
11618 }
11619 (itemsbuf[GET_REF(itemdataref)].weap_data.xofs)=(value/10000);
11620 break;
11621 case IDATAWEAPYOFS:
11622 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11623 {
11624 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11625 break;
11626 }
11627 (itemsbuf[GET_REF(itemdataref)].weap_data.yofs)=(value/10000);
11628 break;
11629
11630
11631 case IDATAHXOFS:
11632 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11633 {
11634 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11635 break;
11636 }
11637 (itemsbuf[GET_REF(itemdataref)].hxofs)=(value/10000);
11638 break;
11639 case IDATAHYOFS:
11640 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11641 {
11642 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11643 break;
11644 }
11645 (itemsbuf[GET_REF(itemdataref)].hyofs)=(value/10000);
11646 break;
11647 case IDATAHXSZ:
11648 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11649 {
11650 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11651 break;
11652 }
11653 (itemsbuf[GET_REF(itemdataref)].hxsz)=(value/10000);
11654 break;
11655 case IDATAHYSZ:
11656 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11657 {
11658 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11659 break;
11660 }
11661 (itemsbuf[GET_REF(itemdataref)].hysz)=(value/10000);
11662 break;
11663 case IDATAHZSZ:
11664 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11665 {
11666 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11667 break;
11668 }
11669 (itemsbuf[GET_REF(itemdataref)].hzsz)=(value/10000);
11670 break;
11671 case IDATADXOFS:
11672 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11673 {
11674 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11675 break;
11676 }
11677 (itemsbuf[GET_REF(itemdataref)].xofs)=(value/10000);
11678 break;
11679 case IDATADYOFS:
11680 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11681 {
11682 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11683 break;
11684 }
11685 (itemsbuf[GET_REF(itemdataref)].yofs)=(value/10000);
11686 break;
11687 case IDATATILEW:
11688 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11689 {
11690 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11691 break;
11692 }
11693 (itemsbuf[GET_REF(itemdataref)].tilew)=(value/10000);
11694 break;
11695 case IDATATILEH:
11696 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11697 {
11698 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11699 break;
11700 }
11701 (itemsbuf[GET_REF(itemdataref)].tileh)=(value/10000);
11702 break;
11703 case IDATAPICKUP:
11704 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11705 {
11706 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11707 break;
11708 }
11709 (itemsbuf[GET_REF(itemdataref)].pickup)=(value/10000);
11710 break;
11711 case IDATAOVERRIDEFL:
11712 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11713 {
11714 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11715 break;
11716 }
11717 (itemsbuf[GET_REF(itemdataref)].overrideFLAGS)=(value/10000);
11718 break;
11719
11720 case IDATATILEWWEAP:
11721 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11722 {
11723 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11724 break;
11725 }
11726 (itemsbuf[GET_REF(itemdataref)].weap_data.tilew)=(value/10000);
11727 break;
11728 case IDATATILEHWEAP:
11729 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11730 {
11731 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11732 break;
11733 }
11734 (itemsbuf[GET_REF(itemdataref)].weap_data.tileh)=(value/10000);
11735 break;
11736 case IDATAOVERRIDEFLWEAP:
11737 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11738 {
11739 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11740 break;
11741 }
11742 (itemsbuf[GET_REF(itemdataref)].weap_data.override_flags)=(value/10000);
11743 break;
11744
11745 case IDATALEVEL:
11746 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11747 {
11748 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11749 break;
11750 }
11751 (itemsbuf[GET_REF(itemdataref)].level)=vbound(value/10000, 0, 512);
11752 flushItemCache();
11753 break;
11754 case IDATAKEEP:
11755 item_flag(item_gamedata, value);
11756 break;
11757 case IDATAAMOUNT:
11758 {
11759 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11760 {
11761 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11762 break;
11763 }
11764 int32_t v = vbound(value/10000, -9999, 16383);
11765 itemsbuf[GET_REF(itemdataref)].amount &= 0x8000;
11766 itemsbuf[GET_REF(itemdataref)].amount |= (abs(v)&0x3FFF)|(v<0?0x4000:0);
11767 break;
11768 }
11769 case IDATAGRADUAL:
11770 {
11771 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11772 {
11773 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11774 break;
11775 }
11776 SETFLAG(itemsbuf[GET_REF(itemdataref)].amount, 0x8000, value!=0);
11777 break;
11778 }
11779 case IDATACONSTSCRIPT:
11780 item_flag(item_passive_script, value);
11781 break;
11782 case IDATASSWIMDISABLED:
11783 item_flag(item_sideswim_disabled, value);
11784 break;
11785 case IDATABUNNYABLE:
11786 item_flag(item_bunny_enabled, value);
11787 break;
11788 case IDATAJINXIMMUNE:
11789 item_flag(item_jinx_immune, value);
11790 break;
11791 case IDATAJINXSWAP:
11792 item_flag(item_flip_jinx, value);
11793 break;
11794 case IDATAUSEBURNSPR:
11795 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11796 {
11797 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11798 }
11799 else SETFLAG(itemsbuf[GET_REF(itemdataref)].weap_data.wflags, WFLAG_UPDATE_IGNITE_SPRITE, value);
11800 break;
11801 case IDATASETMAX:
11802 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11803 {
11804 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11805 break;
11806 }
11807 (itemsbuf[GET_REF(itemdataref)].setmax)=value/10000;
11808 break;
11809
11810 case IDATAMAX:
11811 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11812 {
11813 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11814 break;
11815 }
11816 (itemsbuf[GET_REF(itemdataref)].max)=value/10000;
11817 break;
11818
11819 case IDATAPOWER:
11820
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 182 times.
182 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11821 {
11822 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11823 break;
11824 }
11825 182 (itemsbuf[GET_REF(itemdataref)].power)=value/10000;
11826 182 break;
11827
11828 case IDATACOUNTER:
11829 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11830 {
11831 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11832 break;
11833 }
11834 (itemsbuf[GET_REF(itemdataref)].count)=vbound(value/10000,0,31);
11835 break;
11836
11837 case IDATAPSOUND:
11838 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11839 {
11840 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11841 break;
11842 }
11843 (itemsbuf[GET_REF(itemdataref)].playsound)=vbound(value/10000, 0, 255);
11844 break;
11845
11846 case IDATAUSESOUND:
11847 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11848 {
11849 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11850 break;
11851 }
11852 (itemsbuf[GET_REF(itemdataref)].usesound)=vbound(value/10000, 0, 255);
11853 break;
11854
11855 case IDATAUSESOUND2:
11856 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11857 {
11858 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11859 break;
11860 }
11861 (itemsbuf[GET_REF(itemdataref)].usesound2)=vbound(value/10000, 0, 255);
11862 break;
11863
11864 //2.54
11865 //My additions begin here. -Z
11866 //Stack item to gain next level
11867 case IDATACOMBINE:
11868 item_flag(item_combine, value);
11869 break;
11870 //using a level of an item downgrades to a lower one
11871 case IDATADOWNGRADE:
11872 item_flag(item_downgrade, value);
11873 break;
11874 //Only validate the cost, don't charge it
11875 case IDATAVALIDATE:
11876 item_flag(item_validate_only, value);
11877 break;
11878 case IDATAVALIDATE2:
11879 item_flag(item_validate_only_2, value);
11880 break;
11881
11882
11883 //Keep Old in editor
11884 case IDATAKEEPOLD:
11885 item_flag(item_keep_old, value);
11886 break;
11887 //Ruppes for magic
11888 case IDATARUPEECOST:
11889 item_flag(item_rupee_magic, value);
11890 break;
11891 //can be eaten
11892 case IDATAEDIBLE:
11893 item_flag(item_edible, value);
11894 break;
11895 //Unused at this time
11896 case IDATAFLAGUNUSED:
11897 item_flag(item_unused, value);
11898 break;
11899 //gain lower level items
11900 case IDATAGAINLOWER:
11901 item_flag(item_gain_old, value);
11902 break;
11903 //Set the action script
11904 case IDATASCRIPT:
11905 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11906 {
11907 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11908 break;
11909 }
11910 FFScript::deallocateAllScriptOwned(ScriptType::Item, ri->itemdataref);
11911 itemsbuf[GET_REF(itemdataref)].script=vbound(value/10000,0,255);
11912 break;
11913 case IDATASPRSCRIPT:
11914 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11915 {
11916 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11917 break;
11918 }
11919 itemsbuf[GET_REF(itemdataref)].sprite_script=vbound(value/10000,0,255);
11920 break;
11921
11922 //Hero tile modifier.
11923 case IDATALTM:
11924 {
11925 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11926 {
11927 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11928 break;
11929 }
11930 auto new_value = value/10000;
11931 if (new_value != itemsbuf[GET_REF(itemdataref)].ltm)
11932 cache_tile_mod_clear();
11933 itemsbuf[GET_REF(itemdataref)].ltm = new_value;
11934 break;
11935 }
11936 //Pickup script
11937 case IDATAPSCRIPT:
11938 {
11939
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2760 times.
2760 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11940 {
11941 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11942 break;
11943 }
11944 //Need to get collect script ref, not standard idata ref!
11945
1/2
✓ Branch 0 taken 2760 times.
✗ Branch 1 not taken.
2760 const int32_t new_ref = ri->itemdataref!=0 ? -(GET_REF(itemdataref)) : COLLECT_SCRIPT_ITEM_ZERO;
11946 2760 FFScript::deallocateAllScriptOwned(ScriptType::Item,new_ref);
11947 2760 itemsbuf[GET_REF(itemdataref)].collect_script=vbound(value/10000, 0, 255);
11948 2760 break;
11949 }
11950 //pickup string
11951 case IDATAPSTRING:
11952 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11953 {
11954 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11955 break;
11956 }
11957 itemsbuf[GET_REF(itemdataref)].pstring=vbound(value/10000, 1, 255);
11958 break;
11959 case IDATAPFLAGS:
11960 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11961 {
11962 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11963 break;
11964 }
11965 itemsbuf[GET_REF(itemdataref)].pickup_string_flags=vbound(value/10000, 0, 214748);
11966 break;
11967 case IDATAPICKUPLITEMS:
11968 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11969 {
11970 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11971 break;
11972 }
11973 itemsbuf[GET_REF(itemdataref)].pickup_litems = vbound(value/10000, 0, 214748) & LI_ALL;
11974 break;
11975 case IDATAPICKUPLITEMLEVEL:
11976 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11977 {
11978 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11979 break;
11980 }
11981 itemsbuf[GET_REF(itemdataref)].pickup_litem_level = vbound(value/10000, -1, MAXLEVELS-1);
11982 break;
11983 //magic cost
11984 case IDATAMAGCOST:
11985 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11986 {
11987 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11988 break;
11989 }
11990 itemsbuf[GET_REF(itemdataref)].cost_amount[0]=vbound(value/10000,32767,-32768);
11991 break;
11992 case IDATACOST2:
11993 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11994 {
11995 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11996 break;
11997 }
11998 itemsbuf[GET_REF(itemdataref)].cost_amount[1]=vbound(value/10000,32767,-32768);
11999 break;
12000 case IDATACOOLDOWN:
12001 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
12002 {
12003 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
12004 break;
12005 }
12006 itemsbuf[GET_REF(itemdataref)].cooldown = zc_max(value/10000,0);
12007 break;
12008 //cost counter ref
12009 case IDATACOSTCOUNTER:
12010 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
12011 {
12012 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
12013 break;
12014 }
12015 itemsbuf[GET_REF(itemdataref)].cost_counter[0]=(vbound(value/10000,-1,32));
12016 break;
12017 case IDATACOSTCOUNTER2:
12018 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
12019 {
12020 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
12021 break;
12022 }
12023 itemsbuf[GET_REF(itemdataref)].cost_counter[1]=(vbound(value/10000,-1,32));
12024 break;
12025 //min hearts to pick up
12026 case IDATAMINHEARTS:
12027 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
12028 {
12029 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
12030 break;
12031 }
12032 itemsbuf[GET_REF(itemdataref)].pickup_hearts=vbound(value/10000, 0, 214748);
12033 break;
12034 //item tile
12035 case IDATATILE:
12036
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 99 times.
99 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
12037 {
12038 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
12039 break;
12040 }
12041 99 itemsbuf[GET_REF(itemdataref)].tile=vbound(value/10000, 0, NEWMAXTILES-1);
12042 99 break;
12043 //flash
12044 case IDATAMISC:
12045 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
12046 {
12047 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
12048 break;
12049 }
12050 itemsbuf[GET_REF(itemdataref)].misc_flags=value/10000;
12051 break;
12052 //cset
12053 case IDATACSET:
12054
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
12055 {
12056 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
12057 break;
12058 }
12059
12060 13 itemsbuf[GET_REF(itemdataref)].csets = (itemsbuf[GET_REF(itemdataref)].csets & 0xF0) | vbound(value/10000,0,15);
12061
12062 // If we find quests that broke, use this code.
12063 // if (QHeader.compareVer(2, 55, 9) >= 0)
12064 // itemsbuf[ri->idata].csets = (itemsbuf[ri->idata].csets & 0xF0) | vbound(value/10000,0,15);
12065 // else
12066 // itemsbuf[ri->idata].csets = vbound(value/10000,0,13);
12067 13 break;
12068
12069 case IDATAFLASHCSET:
12070 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
12071 {
12072 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
12073 break;
12074 }
12075
12076 itemsbuf[ri->itemdataref].csets = (itemsbuf[ri->itemdataref].csets & 0xF) | (vbound(value/10000,0,15)<<4);
12077 break;
12078 /*
12079 case IDATAFRAME:
12080 itemsbuf[ri->idata].frame=value/10000;
12081 break;
12082 */
12083 //A.Frames
12084 case IDATAFRAMES:
12085 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
12086 {
12087 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
12088 break;
12089 }
12090 (itemsbuf[GET_REF(itemdataref)].frames)=vbound(value/10000, 0, 214748);
12091 break;
12092 //A.speed
12093 case IDATAASPEED:
12094 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
12095 {
12096 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
12097 break;
12098 }
12099 itemsbuf[GET_REF(itemdataref)].speed=vbound(value/10000, 0, 214748);
12100 break;
12101 //Anim delay
12102 case IDATADELAY:
12103 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
12104 {
12105 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
12106 break;
12107 }
12108 itemsbuf[GET_REF(itemdataref)].delay=vbound(value/10000, 0, 214748);
12109 break;
12110
12111 ///----------------------------------------------------------------------------------------------------//
12112 //LWeapon Variables
12113
12114 case LWPNSCALE:
12115 if ( get_qr(qr_OLDSPRITEDRAWS) )
12116 {
12117 scripting_log_error_with_context("To use this you must disable the quest rule 'Old (Faster) Sprite Drawing'.");
12118 break;
12119 }
12120 if(auto s=checkLWpn(GET_REF(lwpnref)))
12121 s->scale=(zfix)(value/100.0);
12122
12123 break;
12124
12125 case LWPNX:
12126
2/2
✓ Branch 0 taken 6717 times.
✓ Branch 1 taken 207340 times.
214057 if(auto s=checkLWpn(GET_REF(lwpnref)))
12127
2/2
✓ Branch 0 taken 67473 times.
✓ Branch 1 taken 139867 times.
207340 s->x=get_qr(qr_SPRITEXY_IS_FLOAT) ? zslongToFix(value) : zfix(value/10000);
12128 214057 break;
12129
12130 case SPRITEMAXLWPN:
12131 {
12132 //No bounds check, as this is a universal function and works from NULL pointers!
12133 30 Lwpns.setMax(vbound((value/10000),1,MAX_LWPN_SPRITES));
12134 30 break;
12135 }
12136
12137 case LWPNY:
12138
2/2
✓ Branch 0 taken 6717 times.
✓ Branch 1 taken 207326 times.
214043 if(auto s=checkLWpn(GET_REF(lwpnref)))
12139
2/2
✓ Branch 0 taken 67466 times.
✓ Branch 1 taken 139860 times.
207326 s->y=get_qr(qr_SPRITEXY_IS_FLOAT) ? zslongToFix(value) : zfix(value/10000);
12140
12141 214043 break;
12142
12143 case LWPNZ:
12144
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 971 times.
971 if(auto s=checkLWpn(GET_REF(lwpnref)))
12145 {
12146
2/2
✓ Branch 0 taken 965 times.
✓ Branch 1 taken 6 times.
971 s->z=get_qr(qr_SPRITEXY_IS_FLOAT) ? zslongToFix(value) : zfix(value/10000);
12147
1/2
✓ Branch 0 taken 971 times.
✗ Branch 1 not taken.
971 if(s->z < 0) s->z = 0_zf;
12148 971 }
12149
12150 971 break;
12151
12152 case LWPNJUMP:
12153
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 408 times.
408 if(auto s=checkLWpn(GET_REF(lwpnref)))
12154 408 s->fall=zslongToFix(value)*-100;
12155
12156 408 break;
12157
12158 case LWPNFAKEJUMP:
12159 if(auto s=checkLWpn(GET_REF(lwpnref)))
12160 s->fakefall=zslongToFix(value)*-100;
12161
12162 break;
12163
12164 case LWPNDIR:
12165
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71609 times.
71609 if(auto s=checkLWpn(GET_REF(lwpnref)))
12166 {
12167 71609 s->dir=(value/10000);
12168 71609 s->doAutoRotate(true);
12169 71609 }
12170
12171 71609 break;
12172
12173 case LWPNSPECIAL:
12174 if(auto s=checkLWpn(GET_REF(lwpnref)))
12175 s->specialinfo=(value/10000);
12176
12177 break;
12178
12179 case LWPNGRAVITY:
12180 if(auto s=checkLWpn(GET_REF(lwpnref)))
12181 {
12182 if(value)
12183 s->moveflags |= move_obeys_grav;
12184 else
12185 s->moveflags &= ~move_obeys_grav;
12186 }
12187 break;
12188
12189 case LWPNSTEP:
12190
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 82238 times.
82238 if(auto s=checkLWpn(GET_REF(lwpnref)))
12191 {
12192 // fp math is bad for replay, so always ignore this QR when replay is active.
12193 // TODO: can we just delete this QR? Would it actually break anything? For now,
12194 // just disable for replay and wait for more tests to be played with this QR
12195 // ignored.
12196
3/4
✓ Branch 0 taken 7619 times.
✓ Branch 1 taken 74619 times.
✓ Branch 2 taken 7619 times.
✗ Branch 3 not taken.
82238 if ( get_qr(qr_STEP_IS_FLOAT) || replay_is_active() )
12197 {
12198 82238 s->step= zslongToFix(value / 100);
12199 82238 }
12200 else
12201 {
12202 //old, buggy code replication, round two: Go! -Z
12203 //zfix val = zslongToFix(value);
12204 //val.doFloor();
12205 //s->step = ((val / 100.0).getFloat());
12206
12207 //old, buggy code replication, round THREE: Go! -Z
12208 s->step = ((value/10000)/100.0);
12209 }
12210
12211 82238 }
12212
12213 82238 break;
12214
12215 case LWPNANGLE:
12216
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1939 times.
1939 if(auto s=checkLWpn(GET_REF(lwpnref)))
12217 {
12218 1939 s->angle=(double)(value/10000.0);
12219 1939 s->doAutoRotate();
12220 1939 }
12221
12222 1939 break;
12223
12224 case LWPNDEGANGLE:
12225 if(auto s=checkLWpn(GET_REF(lwpnref)))
12226 {
12227 double rangle = (value / 10000.0) * (PI / 180.0);
12228 s->angle=(double)(rangle);
12229 s->doAutoRotate();
12230 }
12231
12232 break;
12233
12234 case LWPNVX:
12235
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
12236 {
12237 double vy;
12238 6 double vx = (value / 10000.0);
12239
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (s->angular)
12240 vy = zc::math::Sin(s->angle)*s->step;
12241 else
12242 {
12243
5/7
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 2 times.
6 switch(NORMAL_DIR(s->dir))
12244 {
12245 case l_up:
12246 case r_up:
12247 case up:
12248 2 vy = -1.0*s->step;
12249 2 break;
12250 case l_down:
12251 case r_down:
12252 case down:
12253 2 vy = s->step;
12254 2 break;
12255
12256 default:
12257 2 vy = 0;
12258 2 break;
12259 }
12260 }
12261 6 s->angular = true;
12262 6 s->angle=atan2(vy, vx);
12263 6 s->step=FFCore.Distance(0, 0, vx, vy)/10000.0;
12264 6 s->doAutoRotate();
12265 6 }
12266
12267 6 break;
12268
12269 case LWPNVY:
12270
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
12271 {
12272 double vx;
12273 6 double vy = (value / 10000.0);
12274
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (s->angular)
12275 6 vx = zc::math::Cos(s->angle)*s->step;
12276 else
12277 {
12278 switch(NORMAL_DIR(s->dir))
12279 {
12280 case l_up:
12281 case l_down:
12282 case left:
12283 vx = -1.0*s->step;
12284 break;
12285 case r_down:
12286 case r_up:
12287 case right:
12288 vx = s->step;
12289 break;
12290
12291 default:
12292 vx = 0;
12293 break;
12294 }
12295 }
12296 6 s->angular = true;
12297 6 s->angle=atan2(vy, vx);
12298 6 s->step=FFCore.Distance(0, 0, vx, vy)/10000.0;
12299 6 s->doAutoRotate();
12300 6 }
12301
12302 6 break;
12303
12304 case LWPNANGULAR:
12305
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1441 times.
1441 if(auto s=checkLWpn(GET_REF(lwpnref)))
12306 {
12307 1441 s->angular=(value!=0);
12308 1441 s->doAutoRotate(false, true);
12309 1441 }
12310
12311 1441 break;
12312
12313 case LWPNAUTOROTATE:
12314 if(auto s=checkLWpn(GET_REF(lwpnref)))
12315 {
12316 s->autorotate=(value!=0);
12317 s->doAutoRotate(false, true);
12318 }
12319
12320 break;
12321
12322 case LWPNBEHIND:
12323
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6730 times.
6730 if(auto s=checkLWpn(GET_REF(lwpnref)))
12324 6730 s->behind=(value!=0);
12325
12326 6730 break;
12327
12328 case LWPNDRAWTYPE:
12329
1/2
✓ Branch 0 taken 476 times.
✗ Branch 1 not taken.
476 if(auto s=checkLWpn(GET_REF(lwpnref)))
12330 476 s->drawstyle=(value/10000);
12331
12332 476 break;
12333
12334 case LWPNPOWER:
12335
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 148992 times.
148992 if(auto s=checkLWpn(GET_REF(lwpnref)))
12336 148992 s->power=(value/10000);
12337
12338 148992 break;
12339 case LWPNDEAD:
12340
2/2
✓ Branch 0 taken 147806 times.
✓ Branch 1 taken 6717 times.
154523 if(auto s=checkLWpn(GET_REF(lwpnref)))
12341 {
12342 147806 auto dead = value/10000;
12343 147806 s->dead=dead;
12344
2/2
✓ Branch 0 taken 75515 times.
✓ Branch 1 taken 72291 times.
147806 if(dead != 0) s->weapon_dying_frame = false;
12345 147806 }
12346 154523 break;
12347
12348 case LWPNTYPE:
12349 if(auto s=checkLWpn(GET_REF(lwpnref)))
12350 s->id=(value/10000);
12351
12352 break;
12353
12354 case LWPNTILE:
12355
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2464 times.
2464 if(auto s=checkLWpn(GET_REF(lwpnref)))
12356 2464 s->tile=(value/10000);
12357
12358 2464 break;
12359
12360 case LWPNSCRIPTTILE:
12361
1/2
✓ Branch 0 taken 3263 times.
✗ Branch 1 not taken.
3263 if(auto s=checkLWpn(GET_REF(lwpnref)))
12362 3263 s->scripttile=vbound((value/10000),-1,NEWMAXTILES-1);
12363
12364 3263 break;
12365
12366 case LWPNSCRIPTFLIP:
12367 if(auto s=checkLWpn(GET_REF(lwpnref)))
12368 s->scriptflip=vbound((value/10000),-1,127);
12369
12370 break;
12371
12372 case LWPNCSET:
12373
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26540 times.
26540 if(auto s=checkLWpn(GET_REF(lwpnref)))
12374 26540 s->cs=(value/10000)&15;
12375
12376 26540 break;
12377
12378 case LWPNFLASHCSET:
12379
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
12380 6 (s->o_cset)|=(value/10000)<<4;
12381
12382 6 break;
12383
12384 case LWPNFRAMES:
12385
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 429 times.
429 if(auto s=checkLWpn(GET_REF(lwpnref)))
12386 429 s->frames=(value/10000);
12387
12388 429 break;
12389
12390 case LWPNFRAME:
12391
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
12392 6 s->aframe=(value/10000);
12393
12394 6 break;
12395
12396 case LWPNASPEED:
12397
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 787 times.
787 if(auto s=checkLWpn(GET_REF(lwpnref)))
12398 787 s->o_speed=(value/10000);
12399
12400 787 break;
12401
12402 case LWPNFLASH:
12403
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
12404 6 s->flash=(value/10000);
12405
12406 6 break;
12407
12408 case LWPNFLIP:
12409
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 885 times.
885 if(auto s=checkLWpn(GET_REF(lwpnref)))
12410 885 s->flip=(value/10000);
12411
12412 885 break;
12413
12414 case LWPNROTATION:
12415
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4922 times.
4922 if ( get_qr(qr_OLDSPRITEDRAWS) )
12416 {
12417 scripting_log_error_with_context("To use this you must disable the quest rule 'Old (Faster) Sprite Drawing'.");
12418 break;
12419 }
12420
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4922 times.
4922 if(auto s=checkLWpn(GET_REF(lwpnref)))
12421 4922 s->rotation=(value/10000);
12422
12423 4922 break;
12424
12425 case LWPNEXTEND:
12426
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 839 times.
839 if(auto s=checkLWpn(GET_REF(lwpnref)))
12427 839 s->extend=(value/10000);
12428
12429 839 break;
12430
12431 case LWPNOTILE:
12432
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2465 times.
2465 if(auto s=checkLWpn(GET_REF(lwpnref)))
12433 {
12434 2465 s->o_tile=(value/10000);
12435 2465 s->ref_o_tile=(value/10000);
12436 //s->script_wrote_otile=1; //Removing this as of 26th October, 2019 -Z
12437 //if at some future point we WANT writing ->Tile to also overwrite ->OriginalTile,
12438 //then either the user will need to manually write tile, or we can add a QR and
12439 // write ->tile here. 'script_wrote_otile' is out.
12440 2465 }
12441 2465 break;
12442
12443 case LWPNOCSET:
12444
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
12445 6 (s->o_cset)|=(value/10000)&15;
12446
12447 6 break;
12448
12449 case LWPNHXOFS:
12450
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71310 times.
71310 if(auto s=checkLWpn(GET_REF(lwpnref)))
12451 71310 (s->hxofs)=(value/10000);
12452
12453 71310 break;
12454
12455 case LWPNHYOFS:
12456
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71308 times.
71308 if(auto s=checkLWpn(GET_REF(lwpnref)))
12457 71308 (s->hyofs)=(value/10000);
12458
12459 71308 break;
12460
12461 case LWPNXOFS:
12462
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1768 times.
1768 if(auto s=checkLWpn(GET_REF(lwpnref)))
12463 1768 (s->xofs)=(zfix)(value/10000);
12464
12465 1768 break;
12466
12467 case LWPNYOFS:
12468
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 70954 times.
70954 if(auto s=checkLWpn(GET_REF(lwpnref)))
12469
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 70954 times.
70954 (s->yofs)=(zfix)(value/10000)+(get_qr(qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
12470
12471 70954 break;
12472
12473 case LWPNSHADOWXOFS:
12474 if(auto s=checkLWpn(GET_REF(lwpnref)))
12475 (s->shadowxofs)=(zfix)(value/10000);
12476
12477 break;
12478
12479 case LWPNSHADOWYOFS:
12480 if(auto s=checkLWpn(GET_REF(lwpnref)))
12481 (s->shadowyofs)=(zfix)(value/10000);
12482
12483 break;
12484
12485 case LWPNTOTALDYOFFS:
12486 break; //READ-ONLY
12487
12488 case LWPNZOFS:
12489
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
12490 6 (s->zofs)=(zfix)(value/10000);
12491
12492 6 break;
12493
12494 case LWPNHXSZ:
12495
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72525 times.
72525 if(auto s=checkLWpn(GET_REF(lwpnref)))
12496 72525 (s->hit_width)=(value/10000);
12497
12498 72525 break;
12499
12500 case LWPNHYSZ:
12501
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72542 times.
72542 if(auto s=checkLWpn(GET_REF(lwpnref)))
12502 72542 (s->hit_height)=(value/10000);
12503
12504 72542 break;
12505
12506 case LWPNHZSZ:
12507
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
12508 6 (s->hzsz)=(value/10000);
12509
12510 6 break;
12511
12512 case LWPNTXSZ:
12513
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 833 times.
833 if(auto s=checkLWpn(GET_REF(lwpnref)))
12514 833 (s->txsz)=vbound((value/10000),1,20);
12515
12516 833 break;
12517
12518 case LWPNTYSZ:
12519
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 833 times.
833 if(auto s=checkLWpn(GET_REF(lwpnref)))
12520 833 (s->tysz)=vbound((value/10000),1,20);
12521
12522 833 break;
12523
12524 case LWPNCOLLDET:
12525
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25012 times.
25012 if(auto s=checkLWpn(GET_REF(lwpnref)))
12526 25012 (s->scriptcoldet) = value;
12527
12528 25012 break;
12529
12530 case LWPNENGINEANIMATE:
12531 if(auto s=checkLWpn(GET_REF(lwpnref)))
12532 (s->do_animation)=value;
12533
12534 break;
12535
12536 case LWPNPARENT:
12537 {
12538 //int32_t pitm = (vbound(value/10000,1,(MAXITEMS-1)));
12539
12540
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 if(auto s=checkLWpn(GET_REF(lwpnref)))
12541 42 (s->parentitem)=(vbound(value/10000,-1,(MAXITEMS-1)));
12542 42 break;
12543 }
12544
12545 case LWPNLEVEL:
12546
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if(auto s=checkLWpn(GET_REF(lwpnref)))
12547 12 (s->level)=value/10000;
12548
12549 12 break;
12550
12551 case LWPNSCRIPT:
12552
1/2
✓ Branch 0 taken 68360 times.
✗ Branch 1 not taken.
68360 if(auto s=checkLWpn(GET_REF(lwpnref)))
12553 {
12554 68360 (s->script)=vbound(value/10000,0,NUMSCRIPTWEAPONS-1);
12555
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 68360 times.
68360 if ( get_qr(qr_CLEARINITDONSCRIPTCHANGE))
12556 {
12557
2/2
✓ Branch 0 taken 546880 times.
✓ Branch 1 taken 68360 times.
615240 for(int32_t q=0; q<8; q++)
12558 546880 (s->initD[q]) = 0;
12559 68360 }
12560 68360 on_reassign_script_engine_data(ScriptType::Lwpn, ri->lwpnref);
12561 68360 }
12562 68360 break;
12563
12564 case LWPNUSEWEAPON:
12565
1/2
✓ Branch 0 taken 1130 times.
✗ Branch 1 not taken.
1130 if(auto s=checkLWpn(GET_REF(lwpnref)))
12566 1130 (s->useweapon)=vbound(value/10000,0,255);
12567
12568 1130 break;
12569
12570 case LWPNUSEDEFENCE:
12571 if(auto s=checkLWpn(GET_REF(lwpnref)))
12572 (s->usedefense)=vbound(value/10000,0,255);
12573
12574 break;
12575
12576 case LWPNFALLCLK:
12577 if(auto s=checkLWpn(GET_REF(lwpnref)))
12578 {
12579 if(s->fallclk != 0 && value == 0)
12580 {
12581 s->cs = s->o_cset;
12582 s->tile = s->o_tile;
12583 }
12584 else if(s->fallclk == 0 && value != 0) s->o_cset = s->cs;
12585 s->fallclk = vbound(value/10000,0,70);
12586 }
12587 break;
12588 case LWPNFALLCMB:
12589 if(auto s=checkLWpn(GET_REF(lwpnref)))
12590 {
12591 s->fallCombo = vbound(value/10000,0,MAXCOMBOS-1);
12592 }
12593 break;
12594 case LWPNDROWNCLK:
12595 if(auto s=checkLWpn(GET_REF(lwpnref)))
12596 {
12597 if(s->drownclk != 0 && value == 0)
12598 {
12599 s->cs = s->o_cset;
12600 s->tile = s->o_tile;
12601 }
12602 else if(s->drownclk == 0 && value != 0) s->o_cset = s->cs;
12603 s->drownclk = vbound(value/10000,0,70);
12604 }
12605 break;
12606 case LWPNDROWNCMB:
12607 if(auto s=checkLWpn(GET_REF(lwpnref)))
12608 {
12609 s->drownCombo = vbound(value/10000,0,MAXCOMBOS-1);
12610 }
12611 break;
12612 case LWPNFAKEZ:
12613 if(auto s=checkLWpn(GET_REF(lwpnref)))
12614 {
12615 s->fakez=get_qr(qr_SPRITEXY_IS_FLOAT) ? zslongToFix(value) : zfix(value/10000);
12616 if(s->fakez < 0) s->fakez = 0_zf;
12617 }
12618
12619 break;
12620
12621 case LWPNGLOWRAD:
12622
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 527 times.
527 if(auto s=checkLWpn(GET_REF(lwpnref)))
12623 {
12624 527 s->glowRad = vbound(value/10000,0,255);
12625 527 }
12626 527 break;
12627
12628 case LWPNGLOWSHP:
12629 if(auto s=checkLWpn(GET_REF(lwpnref)))
12630 {
12631 s->glowShape = vbound(value/10000,0,255);
12632 }
12633 break;
12634
12635 case LWPNUNBL:
12636 if(auto s=checkLWpn(GET_REF(lwpnref)))
12637 {
12638 s->unblockable = (value/10000)&WPNUNB_ALL;
12639 }
12640 break;
12641
12642 case LWPNSHADOWSPR:
12643 if(auto s=checkLWpn(GET_REF(lwpnref)))
12644 {
12645 s->spr_shadow = vbound(value/10000, 0, 255);
12646 }
12647 break;
12648 case LWSWHOOKED:
12649 break; //read-only
12650 case LWPNTIMEOUT:
12651
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72192 times.
72192 if(auto s=checkLWpn(GET_REF(lwpnref)))
12652 {
12653 72192 s->weap_timeout = vbound(value/10000,0,214748);
12654 72192 }
12655 72192 break;
12656 case LWPNDEATHITEM:
12657 if(auto s=checkLWpn(GET_REF(lwpnref)))
12658 {
12659 s->death_spawnitem = vbound(value/10000,-1,MAXITEMS-1);
12660 }
12661 break;
12662 case LWPNDEATHDROPSET:
12663 if(auto s=checkLWpn(GET_REF(lwpnref)))
12664 {
12665 s->death_spawndropset = vbound(value/10000,-1,MAXITEMDROPSETS-1);
12666 }
12667 break;
12668 case LWPNDEATHIPICKUP:
12669 if(auto s=checkLWpn(GET_REF(lwpnref)))
12670 {
12671 s->death_item_pflags = value/10000;
12672 }
12673 break;
12674 case LWPNDEATHSPRITE:
12675 if(auto s=checkLWpn(GET_REF(lwpnref)))
12676 {
12677 s->death_sprite = vbound(value/10000,-255,MAXWPNS-1);
12678 }
12679 break;
12680 case LWPNDEATHSFX:
12681 if(auto s=checkLWpn(GET_REF(lwpnref)))
12682 {
12683 s->death_sfx = vbound(value/10000,0,WAV_COUNT);
12684 }
12685 break;
12686 case LWPNLIFTLEVEL:
12687 if(auto s=checkLWpn(GET_REF(lwpnref)))
12688 {
12689 s->lift_level = vbound(value/10000,0,255);
12690 }
12691 break;
12692 case LWPNLIFTTIME:
12693 if(auto s=checkLWpn(GET_REF(lwpnref)))
12694 {
12695 s->lift_time = vbound(value/10000,0,255);
12696 }
12697 break;
12698 case LWPNLIFTHEIGHT:
12699 if(auto s=checkLWpn(GET_REF(lwpnref)))
12700 {
12701 s->lift_height = zslongToFix(value);
12702 }
12703 break;
12704
12705 ///----------------------------------------------------------------------------------------------------//
12706 //EWeapon Variables
12707 case EWPNSCALE:
12708 if ( get_qr(qr_OLDSPRITEDRAWS) )
12709 {
12710 scripting_log_error_with_context("To use this you must disable the quest rule 'Old (Faster) Sprite Drawing'.");
12711 break;
12712 }
12713 if(auto s=checkEWpn(GET_REF(ewpnref)))
12714 s->scale=(zfix)(value/100.0);
12715
12716 break;
12717
12718 case EWPNX:
12719
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 390184 times.
390184 if(auto s=checkEWpn(GET_REF(ewpnref)))
12720
2/2
✓ Branch 0 taken 38745 times.
✓ Branch 1 taken 351439 times.
390184 s->x = (get_qr(qr_SPRITEXY_IS_FLOAT) ? zslongToFix(value) : zfix(value/10000));
12721
12722 390184 break;
12723
12724 case SPRITEMAXEWPN:
12725 {
12726 //No bounds check, as this is a universal function and works from NULL pointers!
12727 30 Ewpns.setMax(vbound((value/10000),1,MAX_EWPN_SPRITES));
12728 30 break;
12729 }
12730
12731 case EWPNY:
12732
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 390781 times.
390781 if(auto s=checkEWpn(GET_REF(ewpnref)))
12733
2/2
✓ Branch 0 taken 38611 times.
✓ Branch 1 taken 352170 times.
390781 s->y = (get_qr(qr_SPRITEXY_IS_FLOAT) ? zslongToFix(value) : zfix(value/10000));
12734
12735 390781 break;
12736
12737 case EWPNZ:
12738
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57530 times.
57530 if(auto s=checkEWpn(GET_REF(ewpnref)))
12739 {
12740
2/2
✓ Branch 0 taken 1291 times.
✓ Branch 1 taken 56239 times.
57530 s->z=get_qr(qr_SPRITEXY_IS_FLOAT) ? zslongToFix(value) : zfix(value/10000);
12741
2/2
✓ Branch 0 taken 57119 times.
✓ Branch 1 taken 411 times.
57530 if(s->z < 0) s->z = 0_zf;
12742 57530 }
12743
12744 57530 break;
12745
12746 case EWPNJUMP:
12747
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55587 times.
55587 if(auto s=checkEWpn(GET_REF(ewpnref)))
12748 55587 s->fall=zslongToFix(value)*-100;
12749
12750 55587 break;
12751
12752 case EWPNFAKEJUMP:
12753 if(auto s=checkEWpn(GET_REF(ewpnref)))
12754 s->fakefall=zslongToFix(value)*-100;
12755
12756 break;
12757
12758 case EWPNDIR:
12759
1/2
✓ Branch 0 taken 227257 times.
✗ Branch 1 not taken.
227257 if(auto s=checkEWpn(GET_REF(ewpnref)))
12760 {
12761 227257 s->dir=(value/10000);
12762 227257 s->doAutoRotate(true);
12763 227257 }
12764
12765 227257 break;
12766
12767 case EWPNLEVEL:
12768
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 117 times.
117 if(auto s=checkEWpn(GET_REF(ewpnref)))
12769 117 s->level=(value/10000);
12770
12771 117 break;
12772
12773 case EWPNGRAVITY:
12774 if(auto s=checkEWpn(GET_REF(ewpnref)))
12775 {
12776 if(value)
12777 s->moveflags |= move_obeys_grav;
12778 else
12779 s->moveflags &= ~move_obeys_grav;
12780 }
12781 break;
12782
12783 case EWPNSTEP:
12784
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 457872 times.
457872 if(auto s=checkEWpn(GET_REF(ewpnref)))
12785 {
12786
3/4
✓ Branch 0 taken 350322 times.
✓ Branch 1 taken 107550 times.
✓ Branch 2 taken 350322 times.
✗ Branch 3 not taken.
457872 if ( get_qr(qr_STEP_IS_FLOAT) || replay_is_active() )
12787 {
12788 457872 s->step= zslongToFix(value / 100);
12789 457872 }
12790 else
12791 {
12792 //old, buggy code replication, round two: Go! -Z
12793 //zfix val = zslongToFix(value);
12794 //val.doFloor();
12795 //s->step = ((val / 100.0).getFloat());
12796
12797 //old, buggy code replication, round THREE: Go! -Z
12798 s->step = ((value/10000)/100.0);
12799 }
12800 457872 }
12801
12802 457872 break;
12803
12804 case EWPNANGLE:
12805
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 305555 times.
305561 if(auto s=checkEWpn(GET_REF(ewpnref)))
12806 {
12807 305555 s->angle=(double)(value/10000.0);
12808 305555 s->doAutoRotate();
12809 305555 }
12810
12811 305561 break;
12812
12813 case EWPNDEGANGLE:
12814
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 93 times.
93 if(auto s=checkEWpn(GET_REF(ewpnref)))
12815 {
12816 93 double rangle = (value / 10000.0) * (PI / 180.0);
12817 93 s->angle=(double)(rangle);
12818 93 s->doAutoRotate();
12819 93 }
12820
12821 93 break;
12822
12823 case EWPNVX:
12824 if(auto s=checkEWpn(GET_REF(ewpnref)))
12825 {
12826 double vy;
12827 double vx = (value / 10000.0);
12828 if (s->angular)
12829 vy = zc::math::Sin(s->angle)*s->step;
12830 else
12831 {
12832 switch(NORMAL_DIR(s->dir))
12833 {
12834 case l_up:
12835 case r_up:
12836 case up:
12837 vy = -1.0*s->step;
12838 break;
12839 case l_down:
12840 case r_down:
12841 case down:
12842 vy = s->step;
12843 break;
12844
12845 default:
12846 vy = 0;
12847 break;
12848 }
12849 }
12850 s->angular = true;
12851 s->angle=atan2(vy, vx);
12852 s->step=FFCore.Distance(0, 0, vx, vy)/10000;
12853 s->doAutoRotate();
12854 }
12855
12856 break;
12857
12858 case EWPNVY:
12859 if(auto s=checkEWpn(GET_REF(ewpnref)))
12860 {
12861 double vx;
12862 double vy = (value / 10000.0);
12863 if (s->angular)
12864 vx = zc::math::Cos(s->angle)*s->step;
12865 else
12866 {
12867 switch(NORMAL_DIR(s->dir))
12868 {
12869 case l_up:
12870 case l_down:
12871 case left:
12872 vx = -1.0*s->step;
12873 break;
12874 case r_down:
12875 case r_up:
12876 case right:
12877 vx = s->step;
12878 break;
12879
12880 default:
12881 vx = 0;
12882 break;
12883 }
12884 }
12885 s->angular = true;
12886 s->angle=atan2(vy, vx);
12887 s->step=FFCore.Distance(0, 0, vx, vy)/10000;
12888 s->doAutoRotate();
12889 }
12890
12891 break;
12892
12893 case EWPNANGULAR:
12894
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 293753 times.
293753 if(auto s=checkEWpn(GET_REF(ewpnref)))
12895 {
12896 293753 s->angular=(value!=0);
12897 293753 s->doAutoRotate(false, true);
12898 293753 }
12899
12900 293753 break;
12901
12902 case EWPNAUTOROTATE:
12903 if(auto s=checkEWpn(GET_REF(ewpnref)))
12904 {
12905 s->autorotate=(value!=0);
12906 s->doAutoRotate(false, true);
12907 }
12908
12909 break;
12910
12911 case EWPNBEHIND:
12912
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7539 times.
7539 if(auto s=checkEWpn(GET_REF(ewpnref)))
12913 7539 s->behind=(value!=0);
12914
12915 7539 break;
12916
12917 case EWPNDRAWTYPE:
12918
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12175 times.
12175 if(auto s=checkEWpn(GET_REF(ewpnref)))
12919 12175 s->drawstyle=(value/10000);
12920
12921 12175 break;
12922
12923 case EWPNPOWER:
12924
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 305977 times.
305977 if(auto s=checkEWpn(GET_REF(ewpnref)))
12925 305977 s->power=(value/10000);
12926
12927 305977 break;
12928
12929 case EWPNDEAD:
12930
1/2
✓ Branch 0 taken 398520 times.
✗ Branch 1 not taken.
398520 if(auto s=checkEWpn(GET_REF(ewpnref)))
12931 {
12932 398520 auto dead = value/10000;
12933 398520 s->dead=dead;
12934
2/2
✓ Branch 0 taken 88001 times.
✓ Branch 1 taken 310519 times.
398520 if(dead != 0) s->weapon_dying_frame = false;
12935 398520 }
12936
12937 398520 break;
12938
12939 case EWPNTYPE:
12940 if(auto s=checkEWpn(GET_REF(ewpnref)))
12941 s->id=(value/10000);
12942
12943 break;
12944
12945 case EWPNTILE:
12946
1/2
✓ Branch 0 taken 74446 times.
✗ Branch 1 not taken.
74446 if(auto s=checkEWpn(GET_REF(ewpnref)))
12947 74446 s->tile=(value/10000);
12948
12949 74446 break;
12950
12951 case EWPNSCRIPTTILE:
12952
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 178 times.
178 if(auto s=checkEWpn(GET_REF(ewpnref)))
12953 178 s->scripttile=vbound((value/10000),-1, NEWMAXTILES-1);
12954
12955 178 break;
12956
12957 case EWPNSCRIPTFLIP:
12958 if(auto s=checkEWpn(GET_REF(ewpnref)))
12959 s->scriptflip=vbound((value/10000),-1, 127);
12960
12961 break;
12962
12963 case EWPNCSET:
12964
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35337 times.
35337 if(auto s=checkEWpn(GET_REF(ewpnref)))
12965 35337 s->cs=(value/10000)&15;
12966
12967 35337 break;
12968
12969 case EWPNFLASHCSET:
12970 if(auto s=checkEWpn(GET_REF(ewpnref)))
12971 (s->o_cset)|=(value/10000)<<4;
12972
12973 break;
12974
12975 case EWPNFRAMES:
12976
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 199 times.
199 if(auto s=checkEWpn(GET_REF(ewpnref)))
12977 199 s->frames=(value/10000);
12978
12979 199 break;
12980
12981 case EWPNFRAME:
12982
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1039 times.
1039 if(auto s=checkEWpn(GET_REF(ewpnref)))
12983 1039 s->aframe=(value/10000);
12984
12985 1039 break;
12986
12987 case EWPNASPEED:
12988
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 199 times.
199 if(auto s=checkEWpn(GET_REF(ewpnref)))
12989 199 s->o_speed=(value/10000);
12990
12991 199 break;
12992
12993 case EWPNFLASH:
12994
1/2
✓ Branch 0 taken 549 times.
✗ Branch 1 not taken.
549 if(auto s=checkEWpn(GET_REF(ewpnref)))
12995 549 s->flash=(value/10000);
12996
12997 549 break;
12998
12999 case EWPNFLIP:
13000
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 78832 times.
78832 if(auto s=checkEWpn(GET_REF(ewpnref)))
13001 78832 s->flip=(value/10000);
13002
13003 78832 break;
13004
13005 case EWPNROTATION:
13006
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1104 times.
1104 if ( get_qr(qr_OLDSPRITEDRAWS) )
13007 {
13008 scripting_log_error_with_context("To use this you must disable the quest rule 'Old (Faster) Sprite Drawing'");
13009 break;
13010 }
13011
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1104 times.
1104 if(auto s=checkEWpn(GET_REF(ewpnref)))
13012 1104 s->rotation=(value/10000);
13013
13014 1104 break;
13015
13016 case EWPNEXTEND:
13017
1/2
✓ Branch 0 taken 156969 times.
✗ Branch 1 not taken.
156969 if(auto s=checkEWpn(GET_REF(ewpnref)))
13018 156969 s->extend=(value/10000);
13019
13020 156969 break;
13021
13022 case EWPNOTILE:
13023
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4552 times.
4552 if(auto s=checkEWpn(GET_REF(ewpnref)))
13024 {
13025 4552 s->o_tile=(value/10000);
13026 4552 s->ref_o_tile=(value/10000);
13027 4552 }
13028
13029 4552 break;
13030
13031 case EWPNOCSET:
13032 if(auto s=checkEWpn(GET_REF(ewpnref)))
13033 (s->o_cset)|=(value/10000)&15;
13034
13035 break;
13036
13037 case EWPNHXOFS:
13038
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 194229 times.
194229 if(auto s=checkEWpn(GET_REF(ewpnref)))
13039 194229 (s->hxofs)=(value/10000);
13040
13041 194229 break;
13042
13043 case EWPNHYOFS:
13044
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 193736 times.
193736 if(auto s=checkEWpn(GET_REF(ewpnref)))
13045 193736 (s->hyofs)=(value/10000);
13046
13047 193736 break;
13048
13049 case EWPNXOFS:
13050
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 84990 times.
84994 if(auto s=checkEWpn(GET_REF(ewpnref)))
13051 84990 (s->xofs)=(zfix)(value/10000);
13052
13053 84994 break;
13054
13055 case EWPNYOFS:
13056
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44193 times.
44193 if(auto s=checkEWpn(GET_REF(ewpnref)))
13057
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44193 times.
44193 (s->yofs)=(zfix)(value/10000)+(get_qr(qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
13058
13059 44193 break;
13060
13061 case EWPNSHADOWXOFS:
13062 if(auto s=checkEWpn(GET_REF(ewpnref)))
13063 (s->shadowxofs)=(zfix)(value/10000);
13064
13065 break;
13066
13067 case EWPNSHADOWYOFS:
13068 if(auto s=checkEWpn(GET_REF(ewpnref)))
13069 (s->shadowyofs)=(zfix)(value/10000);
13070
13071 break;
13072
13073 case EWPNZOFS:
13074 if(auto s=checkEWpn(GET_REF(ewpnref)))
13075 (s->zofs)=(zfix)(value/10000);
13076
13077 break;
13078
13079 case EWPNHXSZ:
13080
1/2
✓ Branch 0 taken 325611 times.
✗ Branch 1 not taken.
325611 if(auto s=checkEWpn(GET_REF(ewpnref)))
13081 325611 (s->hit_width)=(value/10000);
13082
13083 325611 break;
13084
13085 case EWPNHYSZ:
13086
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 325024 times.
325024 if(auto s=checkEWpn(GET_REF(ewpnref)))
13087 325024 (s->hit_height)=(value/10000);
13088
13089 325024 break;
13090
13091 case EWPNHZSZ:
13092
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44 times.
44 if(auto s=checkEWpn(GET_REF(ewpnref)))
13093 44 (s->hzsz)=(value/10000);
13094
13095 44 break;
13096
13097 case EWPNTXSZ:
13098
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 202345 times.
202345 if(auto s=checkEWpn(GET_REF(ewpnref)))
13099 202345 (s->txsz)=vbound((value/10000),1,20);
13100
13101 202345 break;
13102
13103 case EWPNTYSZ:
13104
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 202345 times.
202345 if(auto s=checkEWpn(GET_REF(ewpnref)))
13105 202345 (s->tysz)=vbound((value/10000),1,20);
13106
13107 202345 break;
13108
13109 case EWPNCOLLDET:
13110
1/2
✓ Branch 0 taken 37812 times.
✗ Branch 1 not taken.
37812 if(auto s=checkEWpn(GET_REF(ewpnref)))
13111 37812 (s->scriptcoldet)=value;
13112
13113 37812 break;
13114
13115 case EWPNENGINEANIMATE:
13116 if(auto s=checkEWpn(GET_REF(ewpnref)))
13117 (s->do_animation)=value;
13118
13119 break;
13120
13121
13122 case EWPNPARENTUID:
13123 if(auto s=checkEWpn(GET_REF(ewpnref)))
13124 s->setParent(sprite::getByUID(value));
13125 break;
13126
13127 case EWPNPARENT:
13128 if(auto s=checkEWpn(GET_REF(ewpnref)))
13129 (s->parentid)= ( (get_qr(qr_OLDEWPNPARENT)) ? value / 10000 : value );
13130
13131 break;
13132
13133 case EWPNSCRIPT:
13134
1/2
✓ Branch 0 taken 5519 times.
✗ Branch 1 not taken.
5519 if(auto s=checkEWpn(GET_REF(ewpnref)))
13135 {
13136 5519 (s->script)=vbound(value/10000,0,NUMSCRIPTWEAPONS-1);
13137
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5519 times.
5519 if ( get_qr(qr_CLEARINITDONSCRIPTCHANGE))
13138 {
13139
2/2
✓ Branch 0 taken 44152 times.
✓ Branch 1 taken 5519 times.
49671 for(int32_t q=0; q<8; q++)
13140 44152 (s->initD[q]) = 0;
13141 5519 }
13142 5519 on_reassign_script_engine_data(ScriptType::Ewpn, ri->ewpnref);
13143 5519 }
13144 5519 break;
13145
13146 case EWPNFALLCLK:
13147 if(auto s=checkEWpn(GET_REF(ewpnref)))
13148 {
13149 if(s->fallclk != 0 && value == 0)
13150 {
13151 s->cs = s->o_cset;
13152 s->tile = s->o_tile;
13153 }
13154 else if(s->fallclk == 0 && value != 0) s->o_cset = s->cs;
13155 s->fallclk = vbound(value/10000,0,70);
13156 }
13157 break;
13158 case EWPNFALLCMB:
13159 if(auto s=checkEWpn(GET_REF(ewpnref)))
13160 {
13161 s->fallCombo = vbound(value/10000,0,MAXCOMBOS-1);
13162 }
13163 break;
13164 case EWPNDROWNCLK:
13165 if(auto s=checkEWpn(GET_REF(ewpnref)))
13166 {
13167 if(s->drownclk != 0 && value == 0)
13168 {
13169 s->cs = s->o_cset;
13170 s->tile = s->o_tile;
13171 }
13172 else if(s->drownclk == 0 && value != 0) s->o_cset = s->cs;
13173 s->drownclk = vbound(value/10000,0,70);
13174 }
13175 break;
13176 case EWPNDROWNCMB:
13177 if(auto s=checkEWpn(GET_REF(ewpnref)))
13178 {
13179 s->drownCombo = vbound(value/10000,0,MAXCOMBOS-1);
13180 }
13181 break;
13182 case EWPNFAKEZ:
13183 if(auto s=checkEWpn(GET_REF(ewpnref)))
13184 {
13185 s->fakez=get_qr(qr_SPRITEXY_IS_FLOAT) ? zslongToFix(value) : zfix(value/10000);
13186 if(s->fakez < 0) s->fakez = 0_zf;
13187 }
13188
13189 break;
13190
13191 case EWPNGLOWRAD:
13192
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if(auto s=checkEWpn(GET_REF(ewpnref)))
13193 {
13194 4 s->glowRad = vbound(value/10000,0,255);
13195 4 }
13196 4 break;
13197 case EWPNGLOWSHP:
13198 if(auto s=checkEWpn(GET_REF(ewpnref)))
13199 {
13200 s->glowShape = vbound(value/10000,0,255);
13201 }
13202 break;
13203
13204 case EWPNUNBL:
13205
1/2
✓ Branch 0 taken 8364 times.
✗ Branch 1 not taken.
8364 if(auto s=checkEWpn(GET_REF(ewpnref)))
13206 {
13207 8364 s->unblockable = (value/10000)&WPNUNB_ALL;
13208 8364 }
13209 8364 break;
13210
13211 case EWPNSHADOWSPR:
13212 if(auto s=checkEWpn(GET_REF(ewpnref)))
13213 {
13214 s->spr_shadow = vbound(value/10000, 0, 255);
13215 }
13216 break;
13217 case EWSWHOOKED:
13218 break; //read-only
13219 case EWPNTIMEOUT:
13220
1/2
✓ Branch 0 taken 91132 times.
✗ Branch 1 not taken.
91132 if(auto s=checkEWpn(GET_REF(ewpnref)))
13221 {
13222 91132 s->weap_timeout = vbound(value/10000,0,214748);
13223 91132 }
13224 91132 break;case EWPNDEATHITEM:
13225 if(auto s=checkEWpn(GET_REF(ewpnref)))
13226 {
13227 s->death_spawnitem = vbound(value/10000,-1,MAXITEMS-1);
13228 }
13229 break;
13230 case EWPNDEATHDROPSET:
13231 if(auto s=checkEWpn(GET_REF(ewpnref)))
13232 {
13233 s->death_spawndropset = vbound(value/10000,-1,MAXITEMDROPSETS-1);
13234 }
13235 break;
13236 case EWPNDEATHIPICKUP:
13237 if(auto s=checkEWpn(GET_REF(ewpnref)))
13238 {
13239 s->death_item_pflags = value/10000;
13240 }
13241 break;
13242 case EWPNDEATHSPRITE:
13243 if(auto s=checkEWpn(GET_REF(ewpnref)))
13244 {
13245 s->death_sprite = vbound(value/10000,-255,MAXWPNS-1);
13246 }
13247 break;
13248 case EWPNDEATHSFX:
13249 if(auto s=checkEWpn(GET_REF(ewpnref)))
13250 {
13251 s->death_sfx = vbound(value/10000,0,WAV_COUNT);
13252 }
13253 break;
13254 case EWPNLIFTLEVEL:
13255 if(auto s=checkEWpn(GET_REF(ewpnref)))
13256 {
13257 s->lift_level = vbound(value/10000,0,255);
13258 }
13259 break;
13260 case EWPNLIFTTIME:
13261 if(auto s=checkEWpn(GET_REF(ewpnref)))
13262 {
13263 s->lift_time = vbound(value/10000,0,255);
13264 }
13265 break;
13266 case EWPNLIFTHEIGHT:
13267 if(auto s=checkEWpn(GET_REF(ewpnref)))
13268 {
13269 s->lift_height = zslongToFix(value);
13270 }
13271 break;
13272
13273 ///----------------------------------------------------------------------------------------------------//
13274 //Screen Information
13275
13276 case SCREENSCRDATASIZE:
13277 {
13278 int index = map_screen_index(cur_map, ri->screenref);
13279 if (index < 0) break;
13280
13281 game->scriptDataResize(index, value/10000);
13282 break;
13283 }
13284
13285 ///----------------------------------------------------------------------------------------------------//
13286 //BottleTypes
13287
13288 case BOTTLENEXT:
13289 {
13290 if(bottletype* ptr = checkBottleData(GET_REF(bottletyperef)))
13291 {
13292 ptr->next_type = vbound(value/10000, 0, 64);
13293 }
13294 }
13295 break;
13296
13297 ///----------------------------------------------------------------------------------------------------//
13298 //Viewport
13299
13300 case VIEWPORT_TARGET:
13301 {
13302
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (auto s = ResolveBaseSprite(value))
13303 6 set_viewport_sprite(s);
13304 }
13305 6 break;
13306
13307 case VIEWPORT_MODE:
13308 {
13309 4 int val = value;
13310
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (BC::checkBounds(val, (int)ViewportMode::First, (int)ViewportMode::Last) != SH::_NoError)
13311 {
13312 break;
13313 }
13314
13315 4 viewport_mode = (ViewportMode)val;
13316 }
13317 4 break;
13318
13319 case VIEWPORT_X:
13320 {
13321 360 viewport.x = value / 10000;
13322 }
13323 360 break;
13324
13325 case VIEWPORT_Y:
13326 {
13327 360 viewport.y = value / 10000;
13328 }
13329 360 break;
13330
13331 case VIEWPORT_WIDTH:
13332 {
13333 int val = value / 10000;
13334 if (BC::checkBounds(val, 0, 256) != SH::_NoError)
13335 break;
13336
13337 viewport.w = val;
13338 }
13339 break;
13340
13341 case VIEWPORT_HEIGHT:
13342 {
13343 int val = value / 10000;
13344 if (BC::checkBounds(val, 0, 232) != SH::_NoError)
13345 break;
13346
13347 viewport.h = val;
13348 }
13349 break;
13350
13351 ///----------------------------------------------------------------------------------------------------//
13352 //Screen Variables
13353
13354 #define SET_SCREENDATA_VAR_INT32(member, str) \
13355 { \
13356 get_scr(GET_REF(screenref))->member = vbound((value / 10000),-214747,214747); \
13357 } \
13358
13359 #define SET_SCREENDATA_VAR_INT16(member, str) \
13360 { \
13361 get_scr(GET_REF(screenref))->member = vbound((value / 10000),0,32767); \
13362 } \
13363
13364 #define SET_SCREENDATA_VAR_BYTE(member, str) \
13365 { \
13366 get_scr(GET_REF(screenref))->member = vbound((value / 10000),0,255); \
13367 } \
13368
13369 #define SET_SCREENDATA_BYTE_INDEX(member, str, indexbound) \
13370 { \
13371 int32_t indx = GET_D(rINDEX) / 10000; \
13372 get_scr(GET_REF(screenref))->member[indx] = vbound((value / 10000),0,255); \
13373 }
13374
13375 ///max screen id is higher! vbound properly... -Z
13376 #define SET_SCREENDATA_LAYERSCREEN_INDEX(member, str, indexbound) \
13377 { \
13378 int32_t indx = GET_D(rINDEX) / 10000; \
13379 int32_t scrn_id = value/10000; \
13380 if ( FFCore.quest_format[vFFScript] < 11 ) ++indx; \
13381 if (BC::checkIndex(indx, 1, indexbound) != SH::_NoError) \
13382 { \
13383 } \
13384 else if ( scrn_id > MAPSCRS ) \
13385 { \
13386 Z_scripterrlog("Script attempted to use a mapdata->LayerScreen[%d].\n",scrn_id); \
13387 Z_scripterrlog("Valid Screen values are (0) through (%d).\n",MAPSCRS); \
13388 } \
13389 else get_scr(GET_REF(screenref))->member[indx-1] = vbound((scrn_id),0,MAPSCRS); \
13390 }
13391
13392 #define SET_SCREENDATA_FLAG(member, str) \
13393 { \
13394 int32_t flag = (value/10000); \
13395 if ( flag != 0 ) \
13396 { \
13397 get_scr(GET_REF(screenref))->member|=flag; \
13398 } \
13399 else get_scr(GET_REF(screenref))->.member|= ~flag; \
13400 } \
13401
13402 #define SET_SCREENDATA_BOOL_INDEX(member, str, indexbound) \
13403 { \
13404 int32_t indx = GET_D(rINDEX) / 10000; \
13405 if(indx < 0 || indx > indexbound ) \
13406 { \
13407 Z_scripterrlog("Invalid Index passed to Screen->%s[]: %d\n", (indx), str); \
13408 break; \
13409 } \
13410 get_scr(GET_REF(screenref))->member[indx] =( (value/10000) ? 1 : 0 ); \
13411 }
13412
13413 case SCREENDATAVALID:
13414 {
13415 SET_SCREENDATA_VAR_BYTE(valid, "Valid"); //b
13416 mark_current_region_handles_dirty();
13417 break;
13418 }
13419 case SCREENDATAGUY: SET_SCREENDATA_VAR_BYTE(guy, "Guy"); break; //b
13420 case SCREENDATASTRING: SET_SCREENDATA_VAR_INT32(str, "String"); break; //w
13421 case SCREENDATAROOM: SET_SCREENDATA_VAR_BYTE(room, "RoomType"); break; //b
13422 case SCREENDATAITEM:
13423 {
13424 auto v = vbound((value / 10000),-1,255);
13425 auto scr = get_scr(GET_REF(screenref));
13426 if(v > -1)
13427 scr->item = v;
13428 scr->hasitem = v > -1;
13429 break;
13430 }
13431 case SCREENDATAHASITEM: SET_SCREENDATA_VAR_BYTE(hasitem, "HasItem"); break; //b
13432 case SCREENDATADOORCOMBOSET: SET_SCREENDATA_VAR_INT32(door_combo_set, "DoorComboSet"); break; //w
13433 case SCREENDATAWARPRETURNC: SET_SCREENDATA_VAR_INT32(warpreturnc, "WarpReturnC"); break; //w
13434 case SCREENDATASTAIRX: SET_SCREENDATA_VAR_BYTE(stairx, "StairsX"); break; //b
13435 case SCREENDATASTAIRY: SET_SCREENDATA_VAR_BYTE(stairy, "StairsY"); break; //b
13436 case SCREENDATAITEMX: SET_SCREENDATA_VAR_BYTE(itemx, "ItemX"); break; //itemx
13437 case SCREENDATAITEMY: SET_SCREENDATA_VAR_BYTE(itemy, "ItemY"); break; //itemy
13438 case SCREENDATACOLOUR: SET_SCREENDATA_VAR_INT32(color, "CSet"); break; //w
13439 case SCREENDATAENEMYFLAGS: SET_SCREENDATA_VAR_BYTE(flags11, "EnemyFlags"); break; //b
13440 case SCREENDATADOOR: SET_SCREENDATA_BYTE_INDEX(door, "Door", 3); break; //b, 4 of these
13441 case SCREENDATAEXITDIR: SET_SCREENDATA_VAR_BYTE(exitdir, "ExitDir"); break; //b
13442 14 case SCREENDATAPATTERN: SET_SCREENDATA_VAR_BYTE(pattern, "Pattern"); break; //b
13443 case SCREENDATAWARPARRIVALX: SET_SCREENDATA_VAR_BYTE(warparrivalx, "WarpArrivalX"); break; //b
13444 case SCREENDATAWARPARRIVALY: SET_SCREENDATA_VAR_BYTE(warparrivaly, "WarpArrivalY"); break; //b
13445 case SCREENDATASIDEWARPINDEX: SET_SCREENDATA_VAR_BYTE(sidewarpindex, "SideWarpIndex"); break; //b
13446 case SCREENDATACATCHALL: SET_SCREENDATA_VAR_INT32(catchall, "Catchall"); break; //W
13447
13448 case SCREENDATACSENSITIVE: SET_SCREENDATA_VAR_BYTE(csensitive, "CSensitive"); break; //B
13449 case SCREENDATANORESET: SET_SCREENDATA_VAR_INT32(noreset, "NoReset"); break; //W
13450 case SCREENDATANOCARRY: SET_SCREENDATA_VAR_INT32(nocarry, "NoCarry"); break; //W
13451
13452 case SCREENDATATIMEDWARPTICS: SET_SCREENDATA_VAR_INT32(timedwarptics, "TimedWarpTimer"); break; //W
13453 case SCREENDATANEXTMAP: SET_SCREENDATA_VAR_BYTE(nextmap, "NextMap"); break; //B
13454 case SCREENDATANEXTSCREEN: SET_SCREENDATA_VAR_BYTE(nextscr, "NextScreen"); break; //B
13455 case SCREENDATAVIEWX: break;//SET_SCREENDATA_VAR_INT32(viewX, "ViewX"); break; //W
13456 case SCREENDATAVIEWY: break;//SET_SCREENDATA_VAR_INT32(viewY, "ViewY"); break; //W
13457 case SCREENDATASCREENWIDTH: break;//SET_SCREENDATA_VAR_BYTE(scrWidth, "Width"); break; //B
13458 case SCREENDATASCREENHEIGHT: break;//SET_SCREENDATA_VAR_BYTE(scrHeight, "Height"); break; //B
13459 case SCREENDATAENTRYX:
13460 {
13461 30 int32_t newx = vbound((value/10000),0,255);
13462 30 get_scr(GET_REF(screenref))->entry_x = newx;
13463
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 20 times.
30 if ( get_qr(qr_WRITE_ENTRYPOINTS_AFFECTS_HEROCLASS) )
13464 {
13465 20 Hero.respawn_x = (zfix)(newx);
13466 20 }
13467 30 break;
13468 }
13469 case SCREENDATAENTRYY:
13470 {
13471
13472 30 int32_t newy = vbound((value/10000),0,175);
13473 30 get_scr(GET_REF(screenref))->entry_y = newy;
13474
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 20 times.
30 if ( get_qr(qr_WRITE_ENTRYPOINTS_AFFECTS_HEROCLASS) )
13475 {
13476 20 Hero.respawn_y = (zfix)(newy);
13477 20 }
13478 30 break; //B
13479 }
13480
13481 case SCREENDATANUMFF:
13482 {
13483 break;
13484 }
13485
13486 case SCREENDATAFFINITIALISED:
13487 {
13488 int32_t indx = GET_D(rINDEX) / 10000;
13489 if (indx < 0 || indx > MAX_FFCID)
13490 {
13491 Z_scripterrlog("Invalid Index passed to Screen->%s[]: %d\n", "FFCRunning", (indx));
13492 break;
13493 }
13494 get_script_engine_data(ScriptType::FFC, indx).initialized = (value/10000) ? true : false;
13495 }
13496 break;
13497
13498 case SCREENDATASCRIPTENTRY:
13499 {
13500 Z_scripterrlog("Unimplemented: %s\n", "ScriptEntry");
13501 }
13502 break;
13503 case SCREENDATASCRIPTOCCUPANCY:
13504 {
13505 Z_scripterrlog("Unimplemented: %s\n", "ScriptOccupancy");
13506 }
13507 break;
13508 case SCREENDATASCRIPTEXIT:
13509 {
13510 Z_scripterrlog("Unimplemented: %s\n", "ExitScript");
13511 }
13512 break;
13513
13514 case SCREENDATAOCEANSFX:
13515 {
13516 int32_t v = vbound(value/10000, 0, 255);
13517 auto scr = get_scr(GET_REF(screenref));
13518 if (scr == hero_scr && scr->oceansfx != v)
13519 {
13520 stop_sfx(scr->oceansfx);
13521 scr->oceansfx = v;
13522 cont_sfx(scr->oceansfx);
13523 }
13524 break;
13525 }
13526 case SCREENDATABOSSSFX: SET_SCREENDATA_VAR_BYTE(bosssfx, "BossSFX"); break; //B
13527 10 case SCREENDATASECRETSFX: SET_SCREENDATA_VAR_BYTE(secretsfx, "SecretSFX"); break; //B
13528 case SCREENDATAHOLDUPSFX: SET_SCREENDATA_VAR_BYTE(holdupsfx, "ItemSFX"); break; //B
13529 case SCREENDATASCREENMIDI:
13530 {
13531 get_scr(GET_REF(screenref))->screen_midi = vbound((value / 10000)-(MIDIOFFSET_MAPSCR-MIDIOFFSET_ZSCRIPT),-1,32767);
13532 break;
13533 }
13534 case SCREENDATA_GRAVITY_STRENGTH:
13535 {
13536 get_scr(GET_REF(screenref))->screen_gravity = zslongToFix(value);
13537 break;
13538 }
13539 case SCREENDATA_TERMINAL_VELOCITY:
13540 {
13541 get_scr(GET_REF(screenref))->screen_terminal_v = zslongToFix(value);
13542 break;
13543 }
13544 case SCREENDATALENSLAYER: SET_SCREENDATA_VAR_BYTE(lens_layer, "LensLayer"); break; //B, OLD QUESTS ONLY?
13545
13546 case SCREENDATAGUYCOUNT:
13547 {
13548 int mi = mapind(cur_map, GET_REF(screenref));
13549 if(mi > -1)
13550 game->guys[mi] = vbound(value/10000,10,0);
13551 break;
13552 }
13553 case SCREENDATAEXDOOR:
13554 {
13555 int mi = mapind(cur_map, GET_REF(screenref));
13556 if(mi < 0) break;
13557 int dir = SH::read_stack(ri->sp+1) / 10000;
13558 int ind = SH::read_stack(ri->sp+0) / 10000;
13559 if(unsigned(dir) > 3)
13560 Z_scripterrlog("Invalid dir '%d' passed to 'Screen->SetExDoor()'; must be 0-3\n", dir);
13561 else if(unsigned(ind) > 7)
13562 Z_scripterrlog("Invalid index '%d' passed to 'Screen->SetExDoor()'; must be 0-7\n", ind);
13563 else
13564 set_xdoorstate_mi(mi, dir, ind);
13565 break;
13566 }
13567
13568 //These use the same method as SetScreenD
13569 case SCREENWIDTH:
13570 // FFScript::set_screenWidth(&TheMaps[(GET_D(rINDEX2) / 10000) * MAPSCRS + (GET_D(rINDEX)/10000)], value/10000);
13571 break;
13572
13573 case SCREENHEIGHT:
13574 // FFScript::set_screenHeight(&TheMaps[(GET_D(rINDEX2) / 10000) * MAPSCRS + (GET_D(rINDEX)/10000)], value/10000);
13575 break;
13576
13577 case SCREENVIEWX:
13578 // FFScript::set_screenViewX(&TheMaps[(GET_D(rINDEX2) / 10000) * MAPSCRS + (GET_D(rINDEX)/10000)], value/10000);
13579 break;
13580
13581 case SCREENVIEWY:
13582 // FFScript::set_screenViewY(&TheMaps[(GET_D(rINDEX2) / 10000) * MAPSCRS + (GET_D(rINDEX)/10000)], value/10000);
13583 break;
13584
13585 //These use the method of SetScreenEnemy
13586
13587 case GDD:
13588 write_array(game->global_d, GET_D(rINDEX) / 10000, value);
13589 break;
13590
13591 case SDDD:
13592 27297 FFScript::set_screen_d((GET_D(rINDEX))/10000 + ((get_currdmap())<<7), GET_D(rINDEX2)/10000, value);
13593 27297 break;
13594
13595 case SDDDD:
13596 537 FFScript::set_screen_d(GET_D(rINDEX2)/10000 + ((GET_D(rINDEX)/10000)<<7), GET_D(rEXP1)/10000, value);
13597 537 break;
13598
13599 case SCREENSCRIPT:
13600 {
13601 mapscr* scr = get_scr(GET_REF(screenref));
13602
13603 if ( get_qr(qr_CLEARINITDONSCRIPTCHANGE))
13604 {
13605 for(int32_t q=0; q<8; q++)
13606 scr->screeninitd[q] = 0;
13607 }
13608
13609 scr->script=vbound(value/10000, 0, NUMSCRIPTSCREEN-1);
13610 on_reassign_script_engine_data(ScriptType::Screen, ri->screenref);
13611 break;
13612 }
13613
13614 case LIT:
13615 900 set_lights(value);
13616 900 break;
13617
13618 case WAVY:
13619 7396 wavy=value/10000;
13620 7396 break;
13621
13622 case QUAKE:
13623 6728 quakeclk=value/10000;
13624 6728 break;
13625
13626 case ROOMTYPE:
13627 get_scr(GET_REF(screenref))->room=value/10000; break; //this probably doesn't work too well...
13628
13629 case ROOMDATA:
13630 11 get_scr(GET_REF(screenref))->catchall=value/10000;
13631 11 break;
13632
13633 case PUSHBLOCKLAYER:
13634 mblock2.blockLayer=vbound(value/10000, 0, 6);
13635 break;
13636
13637 case PUSHBLOCKCOMBO:
13638 mblock2.bcombo=value/10000;
13639 break;
13640
13641 case PUSHBLOCKCSET:
13642 mblock2.cs=value/10000;
13643 mblock2.oldcset=value/10000;
13644 break;
13645
13646 case UNDERCOMBO:
13647 get_scr(GET_REF(screenref))->undercombo=value/10000;
13648 break;
13649
13650 case UNDERCSET:
13651 get_scr(GET_REF(screenref))->undercset=value/10000;
13652 break;
13653
13654 case SCREEN_DRAW_ORIGIN:
13655
1/2
✓ Branch 0 taken 1853535 times.
✗ Branch 1 not taken.
1853535 if (BC::checkBounds(value, (int)DrawOrigin::First, (int)DrawOrigin::Last) != SH::_NoError)
13656 break;
13657
13658 1853535 ri->screen_draw_origin = (DrawOrigin)value;
13659 1853535 break;
13660
13661 case SCREEN_DRAW_ORIGIN_TARGET:
13662 {
13663
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 606224 times.
606224 if (ResolveBaseSprite(value))
13664 606224 ri->screen_draw_origin_target = value;
13665
13666 606224 break;
13667 }
13668
13669 ///----------------------------------------------------------------------------------------------------//
13670 //New Datatype Variables
13671
13672 ///----------------------------------------------------------------------------------------------------//
13673 //spritedata sp-> Variables
13674 case SPRITEDATATILE: SET_SPRITEDATA_VAR_INT(tile, "Tile"); break;
13675 case SPRITEDATAMISC: SET_SPRITEDATA_VAR_BYTE(misc, "Misc"); break;
13676 case SPRITEDATACSETS:
13677 {
13678 if(unsigned(GET_REF(spritedataref)) > (MAXWPNS-1) )
13679 {
13680 Z_scripterrlog("Invalid Sprite ID passed to spritedata->CSet: %d\n", GET_REF(spritedataref));
13681 }
13682 else
13683 {
13684 wpnsbuf[GET_REF(spritedataref)].csets &= 0xF0;
13685 wpnsbuf[GET_REF(spritedataref)].csets |= vbound((value / 10000),0,15);
13686 }
13687 break;
13688 }
13689 case SPRITEDATAFLCSET:
13690 {
13691 if(unsigned(GET_REF(spritedataref)) > (MAXWPNS-1) )
13692 {
13693 Z_scripterrlog("Invalid Sprite ID passed to spritedata->FlashCSet: %d\n", GET_REF(spritedataref));
13694 }
13695 else
13696 {
13697 wpnsbuf[GET_REF(spritedataref)].csets &= 0x0F;
13698 wpnsbuf[GET_REF(spritedataref)].csets |= vbound((value / 10000),0,15)<<4;
13699 }
13700 break;
13701 }
13702 case SPRITEDATAFRAMES: SET_SPRITEDATA_VAR_BYTE(frames, "Frames"); break;
13703 case SPRITEDATASPEED: SET_SPRITEDATA_VAR_BYTE(speed, "Speed"); break;
13704 case SPRITEDATATYPE: SET_SPRITEDATA_VAR_BYTE(type, "Type"); break;
13705
13706 ///----------------------------------------------------------------------------------------------------//
13707 //mapdata m-> Variables
13708 //mapdata m-> Variables
13709
13710 #define SET_MAPDATA_VAR_INT32(member) \
13711 { \
13712 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref))) \
13713 { \
13714 m->member = vbound((value / 10000),-214747,214747); \
13715 } \
13716 break; \
13717 } \
13718
13719 #define SET_MAPDATA_VAR_INT16(member) \
13720 { \
13721 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref))) \
13722 { \
13723 m->member = vbound((value / 10000),0,32767); \
13724 } \
13725 break; \
13726 } \
13727
13728 #define SET_MAPDATA_VAR_BYTE(member) \
13729 { \
13730 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref))) \
13731 { \
13732 m->member = vbound((value / 10000),0,255); \
13733 } \
13734 break; \
13735 } \
13736
13737 #define SET_MAPDATA_VAR_INDEX32(member, indexbound) \
13738 { \
13739 int32_t indx = GET_D(rINDEX) / 10000; \
13740 if (BC::checkIndex(indx, 0, indexbound) != SH::_NoError) \
13741 { \
13742 } \
13743 else if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref))) \
13744 { \
13745 m->member[indx] = vbound((value / 10000),-214747,214747); \
13746 } \
13747 break; \
13748 } \
13749
13750 #define SET_MAPDATA_VAR_INDEX16(member, indexbound) \
13751 { \
13752 int32_t indx = GET_D(rINDEX) / 10000; \
13753 if (BC::checkIndex(indx, 0, indexbound) != SH::_NoError) \
13754 { \
13755 } \
13756 else if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref))) \
13757 { \
13758 m->member[indx] = vbound((value / 10000),-32767,32767); \
13759 } \
13760 break; \
13761 } \
13762
13763 #define SET_MAPDATA_BYTE_INDEX(member, indexbound) \
13764 { \
13765 int32_t indx = GET_D(rINDEX) / 10000; \
13766 if (BC::checkIndex(indx, 0, indexbound) != SH::_NoError) \
13767 { \
13768 } \
13769 else if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref))) \
13770 { \
13771 m->member[indx] = vbound((value / 10000),0,255); \
13772 } \
13773 break; \
13774 }\
13775
13776 #define SET_MAPDATA_LAYER_INDEX(member, indexbound) \
13777 { \
13778 int32_t indx = GET_D(rINDEX) / 10000; \
13779 if ( FFCore.quest_format[vFFScript] < 11 ) ++indx; \
13780 if (BC::checkIndex(indx, 1, indexbound) != SH::_NoError) \
13781 { \
13782 } \
13783 else if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref))) \
13784 { \
13785 m->member[indx-1] = vbound((value / 10000),0,255); \
13786 } \
13787 break; \
13788 } \
13789
13790 #define SET_MAPDATA_LAYERSCREEN_INDEX(member, indexbound) \
13791 { \
13792 int32_t indx = GET_D(rINDEX) / 10000; \
13793 if ( FFCore.quest_format[vFFScript] < 11 ) ++indx; \
13794 int32_t scrn_id = value/10000; \
13795 if (BC::checkIndex(indx, 1, indexbound) != SH::_NoError) \
13796 { \
13797 } \
13798 else if ( scrn_id > MAPSCRS ) \
13799 { \
13800 Z_scripterrlog("Script attempted to use a mapdata->LayerScreen[%d].\n",scrn_id); \
13801 Z_scripterrlog("Valid Screen values are (0) through (%d).\n",MAPSCRS); \
13802 } \
13803 else if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref))) \
13804 { \
13805 m->member[indx-1] = vbound((scrn_id),0,MAPSCRS); \
13806 } \
13807 break; \
13808 }\
13809
13810 #define SET_MAPDATA_BOOL_INDEX(member, indexbound) \
13811 { \
13812 int32_t indx = GET_D(rINDEX) / 10000; \
13813 if (BC::checkIndex(indx, 0, indexbound) != SH::_NoError) \
13814 { \
13815 } \
13816 else if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref))) \
13817 { \
13818 m->member[indx] =( (value/10000) ? 1 : 0 ); \
13819 } \
13820 break; \
13821 } \
13822
13823
13824 #define SET_FFC_MAPDATA_BOOL_INDEX(member, indexbound) \
13825 { \
13826 int32_t index = GET_D(rINDEX) / 10000; \
13827 if (auto handle = ResolveMapdataFFC(ri->mapdataref, index)) \
13828 { \
13829 handle.ffc->member =( (value/10000) ? 1 : 0 ); \
13830 } \
13831 break; \
13832 } \
13833
13834 #define SET_MAPDATA_FLAG(member) \
13835 { \
13836 int32_t flag = (value/10000); \
13837 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref))) \
13838 { \
13839 if ( flag != 0 ) \
13840 { \
13841 m->member|=flag; \
13842 } \
13843 else m->.member|= ~flag; \
13844 } \
13845 break; \
13846 } \
13847
13848
1/2
✓ Branch 0 taken 114 times.
✗ Branch 1 not taken.
114 case MAPDATAVALID: SET_MAPDATA_VAR_BYTE(valid); break; //b
13849 case MAPDATAGUY: SET_MAPDATA_VAR_BYTE(guy); break; //b
13850 case MAPDATASTRING: SET_MAPDATA_VAR_INT32(str); break; //w
13851 case MAPDATAROOM: SET_MAPDATA_VAR_BYTE(room); break; //b
13852 case MAPDATAITEM:
13853 {
13854 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
13855 {
13856 auto v = vbound((value / 10000),-1,255);
13857 if(v > -1)
13858 m->item = v;
13859 m->hasitem = v > -1;
13860 }
13861 break;
13862 }
13863 case MAPDATAREGIONID:
13864 {
13865 370 int region_id = value / 10000;
13866
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 370 times.
370 if (BC::checkBounds(region_id, 0, 9) != SH::_NoError)
13867 break;
13868
13869 370 auto result = decode_mapdata_ref(GET_REF(mapdataref));
13870
1/2
✓ Branch 0 taken 370 times.
✗ Branch 1 not taken.
370 if (result.scr)
13871 {
13872
1/2
✓ Branch 0 taken 370 times.
✗ Branch 1 not taken.
370 if (result.type == mapdata_type::CanonicalScreen)
13873 {
13874 370 Regions[result.scr->map].set_region_id(result.screen, region_id);
13875 370 }
13876 else
13877 {
13878 scripting_log_error_with_context("This may only be set for canonical screens");
13879 }
13880 370 }
13881 else
13882 {
13883 scripting_log_error_with_context("mapdata pointer is either invalid or uninitialised");
13884 }
13885 370 break;
13886 }
13887 case MAPDATAHASITEM: SET_MAPDATA_VAR_BYTE(hasitem); break; //b
13888 case MAPDATADOORCOMBOSET: SET_MAPDATA_VAR_INT32(door_combo_set); break; //w
13889 case MAPDATAWARPRETURNC: SET_MAPDATA_VAR_INT32(warpreturnc); break; //w
13890 case MAPDATASTAIRX: SET_MAPDATA_VAR_BYTE(stairx); break; //b
13891 case MAPDATASTAIRY: SET_MAPDATA_VAR_BYTE(stairy); break; //b
13892 case MAPDATAITEMX: SET_MAPDATA_VAR_BYTE(itemx); break; //itemx
13893 case MAPDATAITEMY: SET_MAPDATA_VAR_BYTE(itemy); break; //itemy
13894 case MAPDATACOLOUR: SET_MAPDATA_VAR_INT32(color); break; //w
13895 case MAPDATAENEMYFLAGS: SET_MAPDATA_VAR_BYTE(flags11); break; //b
13896 case MAPDATAEXITDIR: SET_MAPDATA_VAR_BYTE(exitdir); break; //b
13897 case MAPDATAPATTERN: SET_MAPDATA_VAR_BYTE(pattern); break; //b
13898 case MAPDATAWARPARRIVALX: SET_MAPDATA_VAR_BYTE(warparrivalx); break; //b
13899 case MAPDATAWARPARRIVALY: SET_MAPDATA_VAR_BYTE(warparrivaly); break; //b
13900
13901 case MAPDATASIDEWARPINDEX: SET_MAPDATA_VAR_BYTE(sidewarpindex); break; //b
13902 case MAPDATAUNDERCOMBO: SET_MAPDATA_VAR_INT32(undercombo); break; //w
13903 case MAPDATAUNDERCSET: SET_MAPDATA_VAR_BYTE(undercset); break; //b
13904 case MAPDATACATCHALL: SET_MAPDATA_VAR_INT32(catchall); break; //W
13905
13906 case MAPDATACSENSITIVE: SET_MAPDATA_VAR_BYTE(csensitive); break; //B
13907 case MAPDATANORESET: SET_MAPDATA_VAR_INT32(noreset); break; //W
13908 case MAPDATANOCARRY: SET_MAPDATA_VAR_INT32(nocarry); break; //W
13909 case MAPDATATIMEDWARPTICS: SET_MAPDATA_VAR_INT32(timedwarptics); break; //W
13910 case MAPDATANEXTMAP: SET_MAPDATA_VAR_BYTE(nextmap); break; //B
13911 case MAPDATANEXTSCREEN: SET_MAPDATA_VAR_BYTE(nextscr); break; //B
13912 case MAPDATAVIEWX: break;//SET_MAPDATA_VAR_INT32(viewX, "ViewX"); break; //W
13913 case MAPDATASCRIPT:
13914 {
13915 auto result = decode_mapdata_ref(GET_REF(mapdataref));
13916 if (result.scr)
13917 {
13918 if (result.current())
13919 {
13920 if (get_qr(qr_CLEARINITDONSCRIPTCHANGE))
13921 {
13922 for (int q=0; q<8; q++)
13923 result.scr->screeninitd[q] = 0;
13924 }
13925
13926 on_reassign_script_engine_data(ScriptType::Screen, ri->screenref);
13927 }
13928
13929 result.scr->script = vbound(value/10000, 0, NUMSCRIPTSCREEN-1);
13930 }
13931 else
13932 {
13933 Z_scripterrlog("Script attempted to use a mapdata->%s on an invalid pointer\n","Script");
13934 }
13935 break;
13936 }
13937 case MAPDATAVIEWY: break;//SET_MAPDATA_VAR_INT32(viewY, "ViewY"); break; //W
13938 case MAPDATASCREENWIDTH: break;//SET_MAPDATA_VAR_BYTE(scrWidth, "Width"); break; //B
13939 case MAPDATASCREENHEIGHT: break;//SET_MAPDATA_VAR_BYTE(scrHeight, "Height"); break; //B
13940 case MAPDATAENTRYX: SET_MAPDATA_VAR_BYTE(entry_x); break; //B
13941 case MAPDATAENTRYY: SET_MAPDATA_VAR_BYTE(entry_y); break; //B
13942
13943 //Number of ffcs that are in use (have valid data
13944 case MAPDATANUMFF:
13945 {
13946 break;
13947 }
13948
13949 case MAPDATAINTID:
13950 {
13951 9 int32_t index = (GET_D(rINDEX)/10000);
13952 9 int32_t dindex = GET_D(rINDEX2)/10000;
13953
13954
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (BC::checkBounds(dindex, 0, 7) != SH::_NoError)
13955 break;
13956
13957
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (auto handle = ResolveMapdataFFC(ri->mapdataref, index))
13958 9 handle.ffc->initd[dindex] = value;
13959 9 break;
13960 }
13961
13962 case MAPDATASCRIPTENTRY:
13963 {
13964 Z_scripterrlog("Unimplemented: %s\n", "ScriptEntry");
13965 }
13966 break;
13967 case MAPDATASCRIPTOCCUPANCY:
13968 {
13969 Z_scripterrlog("Unimplemented: %s\n", "ScriptOccupancy");
13970 }
13971 break;
13972 case MAPDATASCRIPTEXIT:
13973 {
13974 Z_scripterrlog("Unimplemented: %s\n", "ExitScript");
13975 }
13976 break;
13977
13978 case MAPDATAOCEANSFX:
13979 {
13980 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
13981 {
13982 int32_t v = vbound(value/10000, 0, 255);
13983 if(m == hero_scr && m->oceansfx != v)
13984 {
13985 stop_sfx(m->oceansfx);
13986 m->oceansfx = v;
13987 cont_sfx(m->oceansfx);
13988 }
13989 else m->oceansfx = v;
13990 }
13991 break;
13992 }
13993 case MAPDATABOSSSFX: SET_MAPDATA_VAR_BYTE(bosssfx); break; //B
13994 case MAPDATASECRETSFX: SET_MAPDATA_VAR_BYTE(secretsfx); break; //B
13995 case MAPDATAHOLDUPSFX: SET_MAPDATA_VAR_BYTE(holdupsfx); break; //B
13996 case MAPDATASCREENMIDI:
13997 {
13998 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
13999 {
14000 m->screen_midi = vbound((value / 10000)-(MIDIOFFSET_MAPSCR-MIDIOFFSET_ZSCRIPT),-1,32767);
14001 }
14002 break;
14003 }
14004 case MAPDATA_GRAVITY_STRENGTH:
14005 {
14006 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
14007 {
14008 m->screen_gravity = zslongToFix(value);
14009 }
14010 break;
14011 }
14012 case MAPDATA_TERMINAL_VELOCITY:
14013 {
14014 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
14015 {
14016 m->screen_terminal_v = zslongToFix(value);
14017 }
14018 break;
14019 }
14020 case MAPDATALENSLAYER: SET_MAPDATA_VAR_BYTE(lens_layer); break; //B, OLD QUESTS ONLY?
14021
14022 case MAPDATASCRDATASIZE:
14023 {
14024 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
14025 {
14026 int index = get_ref_map_index(GET_REF(mapdataref));
14027 if (index < 0) break;
14028
14029 game->scriptDataResize(index, value/10000);
14030 }
14031 break;
14032 }
14033 case MAPDATAGUYCOUNT:
14034 {
14035 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
14036 {
14037 int mi = get_mi(GET_REF(mapdataref));
14038 if(mi > -1)
14039 {
14040 game->guys[mi] = vbound(value/10000,10,0);
14041 break;
14042 }
14043 }
14044 break;
14045 }
14046 case MAPDATAEXDOOR:
14047 {
14048 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
14049 {
14050 int mi = get_mi(GET_REF(mapdataref));
14051 if(mi < 0) break;
14052 int dir = SH::read_stack(ri->sp+1) / 10000;
14053 int ind = SH::read_stack(ri->sp+0) / 10000;
14054 if(unsigned(dir) > 3)
14055 Z_scripterrlog("Invalid dir '%d' passed to 'mapdata->SetExDoor()'; must be 0-3\n", dir);
14056 else if(unsigned(ind) > 7)
14057 Z_scripterrlog("Invalid index '%d' passed to 'mapdata->SetExDoor()'; must be 0-7\n", ind);
14058 else
14059 set_xdoorstate_mi(mi, dir, ind);
14060 }
14061 break;
14062 }
14063
14064 ///----------------------------------------------------------------------------------------------------//
14065 //dmapdata dmd-> Variables
14066 case DMAPDATAMAP: //byte
14067 {
14068 DMaps[GET_REF(dmapdataref)].map = ((byte)(value / 10000)) - 1; break;
14069 }
14070 case DMAPDATALEVEL: //word
14071 {
14072 DMaps[GET_REF(dmapdataref)].level = ((word)(value / 10000)); break;
14073 }
14074 case DMAPDATAFLOOR: //byte
14075 {
14076 DMaps[GET_REF(dmapdataref)].floor = ((byte)(value / 10000)); break;
14077 }
14078 case DMAPDATAOFFSET: //char
14079 {
14080 DMaps[GET_REF(dmapdataref)].xoff = ((char)(value / 10000)); break;
14081 }
14082 case DMAPDATACOMPASS: //byte
14083 {
14084 DMaps[GET_REF(dmapdataref)].compass = ((byte)(value / 10000)); break;
14085 }
14086 case DMAPDATAPALETTE: //word
14087 {
14088 168468 DMaps[GET_REF(dmapdataref)].color= ((word)(value / 10000));
14089
2/2
✓ Branch 0 taken 168129 times.
✓ Branch 1 taken 339 times.
168468 if(ri->dmapdataref == cur_dmap)
14090 {
14091 339 loadlvlpal(DMaps[GET_REF(dmapdataref)].color);
14092 339 currcset = DMaps[GET_REF(dmapdataref)].color;
14093 339 }
14094 168468 break;
14095 }
14096 case DMAPDATAMIDI: //byte
14097 {
14098 DMaps[GET_REF(dmapdataref)].midi = ((byte)((value / 10000)+MIDIOFFSET_DMAP)); break;
14099 }
14100 case DMAPDATA_GRAVITY_STRENGTH:
14101 {
14102 DMaps[GET_REF(dmapdataref)].dmap_gravity = zslongToFix(value);
14103 break;
14104 }
14105 case DMAPDATA_TERMINAL_VELOCITY:
14106 {
14107 DMaps[GET_REF(dmapdataref)].dmap_terminal_v = zslongToFix(value);
14108 break;
14109 }
14110 case DMAPDATACONTINUE: //byte
14111 {
14112 DMaps[GET_REF(dmapdataref)].cont = ((byte)(value / 10000)); break;
14113 }
14114 case DMAPDATATYPE: //byte
14115 {
14116 DMaps[GET_REF(dmapdataref)].type = (((byte)(value / 10000))&dmfTYPE) | (DMaps[GET_REF(dmapdataref)].type&~dmfTYPE); break;
14117 }
14118 case DMAPSCRIPT: //byte
14119 {
14120 DMaps[GET_REF(dmapdataref)].script = vbound((value / 10000),0,NUMSCRIPTSDMAP-1);
14121 on_reassign_script_engine_data(ScriptType::DMap, ri->dmapdataref);
14122 break;
14123 }
14124 case DMAPDATASIDEVIEW: //byte, treat as bool
14125 {
14126 DMaps[GET_REF(dmapdataref)].sideview = ((value) ? 1 : 0); break;
14127 }
14128 case DMAPDATAMUISCTRACK: //byte
14129 {
14130 DMaps[GET_REF(dmapdataref)].tmusictrack= ((byte)(value / 10000)); break;
14131 }
14132 case DMAPDATASUBSCRA:
14133 {
14134 bool changed = DMaps[GET_REF(dmapdataref)].active_subscreen != ((byte)(value / 10000));
14135 DMaps[GET_REF(dmapdataref)].active_subscreen= ((byte)(value / 10000));
14136 if(changed&&ri->dmapdataref==cur_dmap)
14137 update_subscreens();
14138 break;
14139 }
14140 case DMAPDATASUBSCRP:
14141 {
14142 5120 bool changed = DMaps[GET_REF(dmapdataref)].passive_subscreen != ((byte)(value / 10000));
14143 5120 DMaps[GET_REF(dmapdataref)].passive_subscreen= ((byte)(value / 10000));
14144
3/4
✓ Branch 0 taken 5120 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5110 times.
✓ Branch 3 taken 10 times.
5120 if(changed&&ri->dmapdataref==cur_dmap)
14145 10 update_subscreens();
14146 5120 break;
14147 }
14148 case DMAPDATASUBSCRO:
14149 {
14150 bool changed = DMaps[GET_REF(dmapdataref)].overlay_subscreen != ((byte)(value / 10000));
14151 DMaps[GET_REF(dmapdataref)].overlay_subscreen = ((byte)(value / 10000));
14152 if(changed&&ri->dmapdataref==cur_dmap)
14153 update_subscreens();
14154 break;
14155 }
14156 case DMAPDATAFLAGS: //int32_t
14157 {
14158 DMaps[GET_REF(dmapdataref)].flags = (value / 10000); break;
14159 }
14160 case DMAPDATAMIRRDMAP:
14161 {
14162 DMaps[GET_REF(dmapdataref)].mirrorDMap = vbound(value / 10000, -1, MAXDMAPS); break;
14163 }
14164 case DMAPDATALOOPSTART:
14165 {
14166 DMaps[GET_REF(dmapdataref)].tmusic_loop_start = value;
14167 if (ri->dmapdataref == cur_dmap)
14168 {
14169 if (FFCore.doing_dmap_enh_music(cur_dmap))
14170 {
14171 zcmusic_set_loop(zcmusic, double(DMaps[cur_dmap].tmusic_loop_start / 10000.0), double(DMaps[cur_dmap].tmusic_loop_end / 10000.0));
14172 }
14173 }
14174 break;
14175 }
14176 case DMAPDATALOOPEND:
14177 {
14178 DMaps[GET_REF(dmapdataref)].tmusic_loop_end = value;
14179 if (ri->dmapdataref == cur_dmap)
14180 {
14181 if (FFCore.doing_dmap_enh_music(cur_dmap))
14182 {
14183 zcmusic_set_loop(zcmusic, double(DMaps[cur_dmap].tmusic_loop_start / 10000.0), double(DMaps[cur_dmap].tmusic_loop_end / 10000.0));
14184 }
14185 }
14186 break;
14187 }
14188 case DMAPDATAXFADEIN:
14189 {
14190 DMaps[GET_REF(dmapdataref)].tmusic_xfade_in = (value / 10000);
14191 break;
14192 }
14193 case DMAPDATAXFADEOUT:
14194 {
14195 DMaps[GET_REF(dmapdataref)].tmusic_xfade_out = (value / 10000);
14196 if (DMaps[cur_dmap].tmusic[0]!=0 && strcmp(DMaps[GET_REF(dmapdataref)].tmusic, zcmusic->filename) == 0)
14197 {
14198 zcmusic->fadeoutframes = (value / 10000);
14199 }
14200 break;
14201 }
14202 case DMAPDATAINTROSTRINGID:
14203 {
14204 DMaps[GET_REF(dmapdataref)].intro_string_id = (value / 10000);
14205 break;
14206 }
14207 case MUSICUPDATECOND:
14208 {
14209 FFCore.music_update_cond = vbound(value / 10000, 0, 255);
14210 break;
14211 }
14212 case DMAPDATAASUBSCRIPT: //byte
14213 {
14214 DMaps[GET_REF(dmapdataref)].active_sub_script = vbound((value / 10000),0,NUMSCRIPTSDMAP-1);
14215 on_reassign_script_engine_data(ScriptType::ScriptedActiveSubscreen, ri->dmapdataref);
14216 break;
14217 }
14218 case DMAPDATAMAPSCRIPT: //byte
14219 {
14220 3450 DMaps[GET_REF(dmapdataref)].onmap_script = vbound((value / 10000),0,NUMSCRIPTSDMAP-1);
14221 3450 on_reassign_script_engine_data(ScriptType::OnMap, ri->dmapdataref);
14222 3450 break;
14223 }
14224 case DMAPDATAPSUBSCRIPT: //byte
14225 {
14226 FFScript::deallocateAllScriptOwned(ScriptType::ScriptedPassiveSubscreen, ri->dmapdataref);
14227 word val = vbound((value / 10000),0,NUMSCRIPTSDMAP-1);
14228 if (FFCore.doscript(ScriptType::ScriptedPassiveSubscreen) && ri->dmapdataref == cur_dmap && val == DMaps[GET_REF(dmapdataref)].passive_sub_script)
14229 break;
14230 DMaps[GET_REF(dmapdataref)].passive_sub_script = val;
14231 if(ri->dmapdataref == cur_dmap)
14232 {
14233 FFCore.doscript(ScriptType::ScriptedPassiveSubscreen) = val != 0;
14234 };
14235 break;
14236 }
14237
14238 ///----------------------------------------------------------------------------------------------------//
14239 //messagedata msgd-> Variables
14240
14241
14242 case MESSAGEDATANEXT: //W
14243 {
14244 42 int32_t ID = GET_REF(msgdataref);
14245
14246
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 if(BC::checkMessage(ID) != SH::_NoError)
14247 break;
14248 else
14249 42 MsgStrings[ID].nextstring = vbound((value/10000), 0, (msg_count-1));
14250 42 break;
14251 }
14252
14253 case MESSAGEDATATILE: //W
14254 {
14255 int32_t ID = GET_REF(msgdataref);
14256
14257 if(BC::checkMessage(ID) != SH::_NoError)
14258 break;
14259 else
14260 MsgStrings[ID].tile = vbound((value/10000), 0, (NEWMAXTILES));
14261 break;
14262 }
14263
14264 case MESSAGEDATACSET: //b
14265 {
14266 int32_t ID = GET_REF(msgdataref);
14267
14268 if(BC::checkMessage(ID) != SH::_NoError)
14269 break;
14270 else
14271 MsgStrings[ID].cset = ((byte)vbound((value/10000), 0, 15));
14272 break;
14273 }
14274 case MESSAGEDATATRANS: //BOOL
14275 {
14276 int32_t ID = GET_REF(msgdataref);
14277
14278 if(BC::checkMessage(ID) != SH::_NoError)
14279 break;
14280 else
14281 (MsgStrings[ID].trans) = ((value)?true:false);
14282 break;
14283 }
14284 case MESSAGEDATAFONT: //B
14285 {
14286 int32_t ID = GET_REF(msgdataref);
14287
14288 if(BC::checkMessage(ID) != SH::_NoError)
14289 break;
14290 else
14291 MsgStrings[ID].font = ((byte)vbound((value/10000), 0, 255));
14292 break;
14293 }
14294 case MESSAGEDATAX: //SHORT
14295 {
14296 36 int32_t ID = GET_REF(msgdataref);
14297
14298
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 if(BC::checkMessage(ID) != SH::_NoError)
14299 break;
14300 else
14301 36 MsgStrings[ID].x = ((int16_t)vbound((value/10000), SHRT_MIN, SHRT_MAX));
14302 36 break;
14303 }
14304 case MESSAGEDATAY: //SHORT
14305 {
14306 36 int32_t ID = GET_REF(msgdataref);
14307
14308
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 if(BC::checkMessage(ID) != SH::_NoError)
14309 break;
14310 else
14311 36 MsgStrings[ID].y = ((int16_t)vbound((value/10000), SHRT_MIN, SHRT_MAX));
14312 36 break;
14313 }
14314 case MESSAGEDATAW: //UNSIGNED SHORT
14315 {
14316 int32_t ID = GET_REF(msgdataref);
14317
14318 if(BC::checkMessage(ID) != SH::_NoError)
14319 break;
14320 else
14321 MsgStrings[ID].w = ((uint16_t)vbound((value/10000), 0, USHRT_MAX));
14322 break;
14323 }
14324 case MESSAGEDATAH: //UNSIGNED SHORT
14325 {
14326 int32_t ID = GET_REF(msgdataref);
14327
14328 if(BC::checkMessage(ID) != SH::_NoError)
14329 break;
14330 else
14331 MsgStrings[ID].h = ((uint16_t)vbound((value/10000), 0, USHRT_MAX));
14332 break;
14333 }
14334 case MESSAGEDATASFX: //BYTE
14335 {
14336 36 int32_t ID = GET_REF(msgdataref);
14337
14338
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 if(BC::checkMessage(ID) != SH::_NoError)
14339 break;
14340 else
14341 36 MsgStrings[ID].sfx = ((byte)vbound((value/10000), 0, 255));
14342 36 break;
14343 }
14344 case MESSAGEDATALISTPOS: //WORD
14345 {
14346 int32_t ID = GET_REF(msgdataref);
14347
14348 if(BC::checkMessage(ID) != SH::_NoError)
14349 break;
14350 else
14351 MsgStrings[ID].listpos = vbound((value/10000), 1, (msg_count-1));
14352 break;
14353 }
14354 case MESSAGEDATAVSPACE: //BYTE
14355 {
14356 int32_t ID = GET_REF(msgdataref);
14357
14358 if(BC::checkMessage(ID) != SH::_NoError)
14359 break;
14360 else
14361 MsgStrings[ID].vspace = ((byte)vbound((value/10000), 0, 255));
14362 break;
14363 }
14364 case MESSAGEDATAHSPACE: //BYTE
14365 {
14366 int32_t ID = GET_REF(msgdataref);
14367
14368 if(BC::checkMessage(ID) != SH::_NoError)
14369 break;
14370 else
14371 MsgStrings[ID].hspace = ((byte)vbound((value/10000), 0, 255));
14372 break;
14373 }
14374 case MESSAGEDATAFLAGS: //BYTE
14375 {
14376 int32_t ID = GET_REF(msgdataref);
14377
14378 if(BC::checkMessage(ID) != SH::_NoError)
14379 break;
14380 else
14381 MsgStrings[ID].stringflags = ((byte)vbound((value/10000), 0, 255));
14382 break;
14383 }
14384 case MESSAGEDATAPORTTILE: //INT
14385 {
14386 int32_t ID = GET_REF(msgdataref);
14387
14388 if(BC::checkMessage(ID) != SH::_NoError)
14389 break;
14390 else
14391 MsgStrings[ID].portrait_tile = vbound((value/10000), 0, (NEWMAXTILES));
14392 break;
14393 }
14394 case MESSAGEDATAPORTCSET: //BYTE
14395 {
14396 int32_t ID = GET_REF(msgdataref);
14397
14398 if(BC::checkMessage(ID) != SH::_NoError)
14399 break;
14400 else
14401 MsgStrings[ID].portrait_cset = ((byte)vbound((value/10000), 0, 15));
14402 break;
14403 }
14404 case MESSAGEDATAPORTX: //BYTE
14405 {
14406 int32_t ID = GET_REF(msgdataref);
14407
14408 if(BC::checkMessage(ID) != SH::_NoError)
14409 break;
14410 else
14411 MsgStrings[ID].portrait_x = ((byte)vbound((value/10000), 0, 255));
14412 break;
14413 }
14414 case MESSAGEDATAPORTY: //BYTE
14415 {
14416 int32_t ID = GET_REF(msgdataref);
14417
14418 if(BC::checkMessage(ID) != SH::_NoError)
14419 break;
14420 else
14421 MsgStrings[ID].portrait_y = ((byte)vbound((value/10000), 0, 255));
14422 break;
14423 }
14424 case MESSAGEDATAPORTWID: //BYTE
14425 {
14426 int32_t ID = GET_REF(msgdataref);
14427
14428 if(BC::checkMessage(ID) != SH::_NoError)
14429 break;
14430 else
14431 MsgStrings[ID].portrait_tw = ((byte)vbound((value/10000), 0, 16));
14432 break;
14433 }
14434 case MESSAGEDATAPORTHEI: //BYTE
14435 {
14436 int32_t ID = GET_REF(msgdataref);
14437
14438 if(BC::checkMessage(ID) != SH::_NoError)
14439 break;
14440 else
14441 MsgStrings[ID].portrait_th = ((byte)vbound((value/10000), 0, 14));
14442 break;
14443 }
14444
14445 ///----------------------------------------------------------------------------------------------------//
14446 //combodata cd-> Setter Variables
14447 //newcombo
14448 #define SET_COMBO_VAR_INT(member) \
14449 { \
14450 if(checkComboRef()) \
14451 { \
14452 screen_combo_modify_pre(GET_REF(combodataref)); \
14453 combobuf[GET_REF(combodataref)].member = vbound((value / 10000),0,214747); \
14454 screen_combo_modify_post(GET_REF(combodataref)); \
14455 \
14456 } \
14457 } \
14458
14459 #define SET_COMBO_VAR_DWORD(member) \
14460 { \
14461 if(checkComboRef()) \
14462 { \
14463 screen_combo_modify_pre(GET_REF(combodataref)); \
14464 combobuf[GET_REF(combodataref)].member = vbound((value / 10000),0,32767); \
14465 screen_combo_modify_post(GET_REF(combodataref)); \
14466 } \
14467 } \
14468
14469 #define SET_COMBO_VAR_BYTE(member) \
14470 { \
14471 if(checkComboRef()) \
14472 { \
14473 screen_combo_modify_pre(GET_REF(combodataref)); \
14474 combobuf[GET_REF(combodataref)].member = vbound((value / 10000),0,255); \
14475 screen_combo_modify_post(GET_REF(combodataref)); \
14476 } \
14477 } \
14478
14479 //comboclass
14480 #define SET_COMBOCLASS_VAR_INT(member) \
14481 { \
14482 if(checkComboRef()) \
14483 { \
14484 combo_class_buf[combobuf[GET_REF(combodataref)].type].member = vbound((value / 10000),0,214747); \
14485 } \
14486 } \
14487
14488 #define SET_COMBOCLASS_VAR_DWORD(member) \
14489 { \
14490 if(checkComboRef()) \
14491 { \
14492 combo_class_buf[combobuf[GET_REF(combodataref)].type].member = vbound((value / 10000),0,32767); \
14493 } \
14494 } \
14495
14496 #define SET_COMBOCLASS_VAR_BYTE(member) \
14497 { \
14498 if(checkComboRef()) \
14499 { \
14500 combo_class_buf[combobuf[GET_REF(combodataref)].type].member = vbound((value / 10000),0,255); \
14501 } \
14502 } \
14503
14504 #define SET_COMBOCLASS_BYTE_INDEX(member, indexbound) \
14505 { \
14506 int32_t indx = GET_D(rINDEX) / 10000; \
14507 if(!checkComboRef()) \
14508 { \
14509 } \
14510 else if ( indx < 0 || indx > indexbound ) \
14511 { \
14512 scripting_log_error_with_context("Invalid Array Index: {}", indx); \
14513 } \
14514 else \
14515 { \
14516 combo_class_buf[combobuf[GET_REF(combodataref)].type].member[indx] = vbound((value / 10000),0,255); \
14517 } \
14518 }
14519
14520 //NEWCOMBO STRUCT
14521 case COMBODTILE: SET_COMBO_VAR_INT(tile); break; //word
14522 case COMBODOTILE:
14523 {
14524
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (!checkComboRef()) break;
14525
14526 9 newcombo& cdata = combobuf[GET_REF(combodataref)];
14527 9 cdata.o_tile = vbound((value / 10000),0,NEWMAXTILES);
14528
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if(get_qr(qr_NEW_COMBO_ANIMATION))
14529 {
14530 9 cdata.tile = cdata.o_tile + ((1+cdata.skipanim)*cdata.cur_frame);
14531
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if(int32_t rowoffset = TILEROW(cdata.tile)-TILEROW(cdata.o_tile))
14532 {
14533 cdata.tile += cdata.skipanimy * rowoffset * TILES_PER_ROW;
14534 }
14535 9 combo_caches::drawing.refresh(GET_REF(combodataref));
14536 9 }
14537 9 break;
14538 }
14539 case COMBODFRAME: SET_COMBO_VAR_BYTE(cur_frame); break; //char
14540 case COMBODACLK: SET_COMBO_VAR_BYTE(aclk); break; //char
14541 case COMBODATASCRIPT: SET_COMBO_VAR_DWORD(script); break; //word
14542 case COMBODASPEED: SET_COMBO_VAR_BYTE(speed); break; //char
14543 case COMBODFLIP: SET_COMBO_VAR_BYTE(flip); break; //char
14544 case COMBODWALK:
14545 {
14546 if (!checkComboRef()) break;
14547
14548 combobuf[GET_REF(combodataref)].walk &= ~0x0F;
14549 combobuf[GET_REF(combodataref)].walk |= (value / 10000)&0x0F;
14550 break;
14551 }
14552 case COMBODEFFECT:
14553 {
14554 if (!checkComboRef()) break;
14555
14556 combobuf[GET_REF(combodataref)].walk &= ~0xF0;
14557 combobuf[GET_REF(combodataref)].walk |= ((value / 10000)&0x0F)<<4;
14558 break;
14559 }
14560 case COMBODTYPE:
14561 {
14562 if (!checkComboRef()) break;
14563
14564 screen_combo_modify_pre(GET_REF(combodataref));
14565 combobuf[GET_REF(combodataref)].type = vbound((value / 10000),0,255);
14566 screen_combo_modify_post(GET_REF(combodataref));
14567 break;
14568 }
14569 case COMBODCSET:
14570 {
14571 if (!checkComboRef()) break;
14572
14573 screen_combo_modify_pre(GET_REF(combodataref));
14574 int8_t v = vbound(value, -8, 7);
14575 combobuf[GET_REF(combodataref)].csets &= ~0xF;
14576 combobuf[GET_REF(combodataref)].csets |= v;
14577 screen_combo_modify_post(GET_REF(combodataref));
14578 break;
14579 }
14580 case COMBODCSET2FLAGS:
14581 {
14582 if (!checkComboRef()) break;
14583
14584 screen_combo_modify_pre(GET_REF(combodataref));
14585 combobuf[GET_REF(combodataref)].csets &= 0xF;
14586 combobuf[GET_REF(combodataref)].csets |= (value&0xF)<<4;
14587 screen_combo_modify_post(GET_REF(combodataref));
14588 break;
14589 }
14590 case COMBODFOO: break; //W
14591 case COMBODFRAMES: SET_COMBO_VAR_BYTE(frames); break; //C
14592 case COMBODNEXTD: SET_COMBO_VAR_INT(nextcombo); break; //W
14593 case COMBODNEXTC: SET_COMBO_VAR_BYTE(nextcset); break; //C
14594 case COMBODFLAG: SET_COMBO_VAR_BYTE(flag); break; //C
14595 case COMBODSKIPANIM: SET_COMBO_VAR_BYTE(skipanim); break; //C
14596 case COMBODNEXTTIMER: SET_COMBO_VAR_DWORD(nexttimer); break; //W
14597 case COMBODAKIMANIMY: SET_COMBO_VAR_BYTE(skipanimy); break; //C
14598 case COMBODANIMFLAGS: SET_COMBO_VAR_BYTE(animflags); break; //C
14599 case COMBODUSRFLAGS: SET_COMBO_VAR_INT(usrflags); break; //LONG
14600 case COMBODTRIGGERITEM:
14601 {
14602 if (!checkComboRef()) break;
14603
14604 if(auto* trig = get_first_combo_trigger())
14605 trig->triggeritem = vbound(value/10000,0,255);
14606 break;
14607 }
14608 case COMBODTRIGGERTIMER:
14609 {
14610 if (!checkComboRef()) break;
14611
14612 screen_combo_modify_pre(GET_REF(combodataref));
14613 if(auto* trig = get_first_combo_trigger())
14614 trig->trigtimer = vbound(value/10000,0,65535);
14615 screen_combo_modify_post(GET_REF(combodataref));
14616 break;
14617 }
14618 case COMBODTRIGGERSFX:
14619 {
14620 if (!checkComboRef()) break;
14621
14622 if(auto* trig = get_first_combo_trigger())
14623 trig->trigsfx = vbound(value/10000,0,255);
14624 break;
14625 }
14626 case COMBODTRIGGERCHANGECMB:
14627 {
14628 if (!checkComboRef()) break;
14629
14630 if(auto* trig = get_first_combo_trigger())
14631 trig->trigchange = vbound(value/10000,-65535,65535);
14632 break;
14633 }
14634 case COMBODTRIGGERPROX:
14635 {
14636 if (!checkComboRef()) break;
14637
14638 if(auto* trig = get_first_combo_trigger())
14639 trig->trigprox = vbound(value/10000,0,65535);
14640 break;
14641 }
14642 case COMBODTRIGGERLIGHTBEAM:
14643 {
14644 if (!checkComboRef()) break;
14645
14646 if(auto* trig = get_first_combo_trigger())
14647 trig->triglbeam = vbound(value/10000,0,32);
14648 break;
14649 }
14650 case COMBODTRIGGERCTR:
14651 {
14652 if (!checkComboRef()) break;
14653
14654 if(auto* trig = get_first_combo_trigger())
14655 trig->trigctr = vbound(value/10000, sscMIN, MAX_COUNTERS-1);
14656 break;
14657 }
14658 case COMBODTRIGGERCTRAMNT:
14659 {
14660 if (!checkComboRef()) break;
14661
14662 if(auto* trig = get_first_combo_trigger())
14663 trig->trigctramnt = vbound(value/10000, -65535, 65535);
14664 break;
14665 }
14666
14667 case COMBODTRIGGERCOOLDOWN:
14668 {
14669 if (!checkComboRef()) break;
14670
14671 if(auto* trig = get_first_combo_trigger())
14672 trig->trigcooldown = vbound(value/10000, 0, 255);
14673 break;
14674 }
14675 case COMBODTRIGGERCOPYCAT:
14676 {
14677 if (!checkComboRef()) break;
14678
14679 if(auto* trig = get_first_combo_trigger())
14680 trig->trigcopycat = vbound(value/10000, 0, 255);
14681 break;
14682 }
14683 case COMBODTRIGITEMPICKUP:
14684 {
14685 const int32_t allowed_pflags = ipHOLDUP | ipTIMER | ipSECRETS | ipCANGRAB;
14686 if (!checkComboRef()) break;
14687
14688 if(auto* trig = get_first_combo_trigger())
14689 trig->spawnip = (value/10000)&allowed_pflags;
14690 break;
14691 }
14692 case COMBODTRIGEXSTATE:
14693 {
14694 if (!checkComboRef()) break;
14695
14696 if(auto* trig = get_first_combo_trigger())
14697 trig->exstate = vbound(value/10000, -1, 31);
14698 break;
14699 }
14700 case COMBODTRIGEXDOORDIR:
14701 {
14702 if (!checkComboRef()) break;
14703
14704 if(auto* trig = get_first_combo_trigger())
14705 trig->exdoor_dir = vbound(value/10000, -1, 3);
14706 break;
14707 }
14708 case COMBODTRIGEXDOORIND:
14709 {
14710 if (!checkComboRef()) break;
14711
14712 if(auto* trig = get_first_combo_trigger())
14713 trig->exdoor_ind = vbound(value/10000, 0, 7);
14714 break;
14715 }
14716 case COMBODTRIGSPAWNENEMY:
14717 {
14718 if (!checkComboRef()) break;
14719
14720 if(auto* trig = get_first_combo_trigger())
14721 trig->spawnenemy = vbound(value/10000, 0, 511);
14722 break;
14723 }
14724 case COMBODTRIGSPAWNITEM:
14725 {
14726 if (!checkComboRef()) break;
14727
14728 if(auto* trig = get_first_combo_trigger())
14729 trig->spawnitem = vbound(value/10000, -255, 255);
14730 break;
14731 }
14732 case COMBODTRIGCSETCHANGE:
14733 {
14734 if (!checkComboRef()) break;
14735
14736 if(auto* trig = get_first_combo_trigger())
14737 trig->trigcschange = vbound(value/10000, -15, 15);
14738 break;
14739 }
14740 case COMBODTRIGLITEMS:
14741 {
14742 if (!checkComboRef()) break;
14743
14744 if(auto* trig = get_first_combo_trigger())
14745 trig->trig_levelitems = (value/10000)&LI_ALL;
14746 break;
14747 }
14748 case COMBODTRIGDMAPLVL:
14749 {
14750 if (!checkComboRef()) break;
14751
14752 if(auto* trig = get_first_combo_trigger())
14753 trig->trigdmlevel = vbound(value/10000, -1, MAXLEVELS-1);
14754 break;
14755 }
14756 case COMBODTRIGTINTR:
14757 {
14758 if (!checkComboRef()) break;
14759
14760 if(auto* trig = get_first_combo_trigger())
14761 trig->trigtint[0] = scripting_write_pal_color(vbound(value/10000, -scripting_max_color_val, scripting_max_color_val));
14762 break;
14763 }
14764 case COMBODTRIGTINTG:
14765 {
14766 if (!checkComboRef()) break;
14767
14768 if(auto* trig = get_first_combo_trigger())
14769 trig->trigtint[1] = scripting_write_pal_color(vbound(value/10000, -scripting_max_color_val, scripting_max_color_val));
14770 break;
14771 }
14772 case COMBODTRIGTINTB:
14773 {
14774 if (!checkComboRef()) break;
14775
14776 if(auto* trig = get_first_combo_trigger())
14777 trig->trigtint[2] = scripting_write_pal_color(vbound(value/10000, -scripting_max_color_val, scripting_max_color_val));
14778 break;
14779 }
14780 case COMBODTRIGLVLPAL:
14781 {
14782 if (!checkComboRef()) break;
14783
14784 if(auto* trig = get_first_combo_trigger())
14785 trig->triglvlpalette = vbound(value/10000, -1, 512);
14786 break;
14787 }
14788 case COMBODTRIGBOSSPAL:
14789 {
14790 if (!checkComboRef()) break;
14791
14792 if(auto* trig = get_first_combo_trigger())
14793 trig->trigbosspalette = vbound(value/10000, -1, 29);
14794 break;
14795 }
14796 case COMBODTRIGQUAKETIME:
14797 {
14798 if (!checkComboRef()) break;
14799
14800 if(auto* trig = get_first_combo_trigger())
14801 trig->trigquaketime = zc_max(value/10000, -1);
14802 break;
14803 }
14804 case COMBODTRIGWAVYTIME:
14805 {
14806 if (!checkComboRef()) break;
14807
14808 if(auto* trig = get_first_combo_trigger())
14809 trig->trigwavytime = zc_max(value/10000, -1);
14810 break;
14811 }
14812 case COMBODTRIGSWORDJINX:
14813 {
14814 if (!checkComboRef()) break;
14815
14816 if(auto* trig = get_first_combo_trigger())
14817 trig->trig_swjinxtime = zc_max(value/10000, -2);
14818 break;
14819 }
14820 case COMBODTRIGITEMJINX:
14821 {
14822 if (!checkComboRef()) break;
14823
14824 if(auto* trig = get_first_combo_trigger())
14825 trig->trig_itmjinxtime = zc_max(value/10000, -2);
14826 break;
14827 }
14828 case COMBODTRIGSHIELDJINX:
14829 {
14830 if (!checkComboRef()) break;
14831
14832 else if(auto* trig = get_first_combo_trigger())
14833 trig->trig_shieldjinxtime = zc_max(value / 10000, -2);
14834 break;
14835 }
14836 case COMBODTRIGSTUN:
14837 {
14838 if (!checkComboRef()) break;
14839
14840 if(auto* trig = get_first_combo_trigger())
14841 trig->trig_stuntime = zc_max(value/10000, -2);
14842 break;
14843 }
14844 case COMBODTRIGBUNNY:
14845 {
14846 if (!checkComboRef()) break;
14847
14848 if(auto* trig = get_first_combo_trigger())
14849 trig->trig_bunnytime = zc_max(value/10000, -2);
14850 break;
14851 }
14852 case COMBODTRIGPUSHTIME:
14853 {
14854 if (!checkComboRef()) break;
14855
14856 if(auto* trig = get_first_combo_trigger())
14857 trig->trig_pushtime = vbound(value/10000, 0, 255);
14858 break;
14859 }
14860 case COMBODLIFTGFXCOMBO:
14861 {
14862 if (!checkComboRef()) break;
14863
14864 combobuf[GET_REF(combodataref)].liftcmb = vbound(value/10000, 0, MAXCOMBOS);
14865 break;
14866 }
14867 case COMBODLIFTGFXCCSET:
14868 {
14869 if (!checkComboRef()) break;
14870
14871 combobuf[GET_REF(combodataref)].liftcs = vbound(value/10000, 0, 13);
14872 break;
14873 }
14874 case COMBODLIFTUNDERCMB:
14875 {
14876 if (!checkComboRef()) break;
14877
14878 combobuf[GET_REF(combodataref)].liftundercmb = vbound(value/10000, 0, MAXCOMBOS);
14879 break;
14880 }
14881 case COMBODLIFTUNDERCS:
14882 {
14883 if (!checkComboRef()) break;
14884
14885 combobuf[GET_REF(combodataref)].liftundercs = vbound(value/10000, 0, 13);
14886 break;
14887 }
14888 case COMBODLIFTDAMAGE:
14889 {
14890 if (!checkComboRef()) break;
14891
14892 combobuf[GET_REF(combodataref)].liftdmg = vbound(value/10000, 0, 255);
14893 break;
14894 }
14895 case COMBODLIFTLEVEL:
14896 {
14897 if (!checkComboRef()) break;
14898
14899 combobuf[GET_REF(combodataref)].liftlvl = vbound(value/10000, 0, 255);
14900 break;
14901 }
14902 case COMBODLIFTITEM:
14903 {
14904 if (!checkComboRef()) break;
14905
14906 combobuf[GET_REF(combodataref)].liftitm = vbound(value/10000, 0, 255);
14907 break;
14908 }
14909 case COMBODLIFTGFXTYPE:
14910 {
14911 if (!checkComboRef()) break;
14912
14913 combobuf[GET_REF(combodataref)].liftgfx = vbound(value/10000, 0, 2);
14914 break;
14915 }
14916 case COMBODLIFTGFXSPRITE:
14917 {
14918 if (!checkComboRef()) break;
14919
14920 combobuf[GET_REF(combodataref)].liftsprite = vbound(value/10000, 0, 255);
14921 break;
14922 }
14923 case COMBODLIFTSFX:
14924 {
14925 if (!checkComboRef()) break;
14926
14927 combobuf[GET_REF(combodataref)].liftsfx = vbound(value/10000, 0, 255);
14928 break;
14929 }
14930 case COMBODLIFTBREAKSPRITE:
14931 {
14932 if (!checkComboRef()) break;
14933
14934 combobuf[GET_REF(combodataref)].liftbreaksprite = vbound(value/10000, -4, 255);
14935 break;
14936 }
14937 case COMBODLIFTBREAKSFX:
14938 {
14939 if (!checkComboRef()) break;
14940
14941 combobuf[GET_REF(combodataref)].liftbreaksfx = vbound(value/10000, 0, 255);
14942 break;
14943 }
14944 case COMBODLIFTHEIGHT:
14945 {
14946 if (!checkComboRef()) break;
14947
14948 combobuf[GET_REF(combodataref)].lifthei = vbound(value/10000, 0, 255);
14949 break;
14950 }
14951 case COMBODLIFTTIME:
14952 {
14953 if (!checkComboRef()) break;
14954
14955 combobuf[GET_REF(combodataref)].lifttime = vbound(value/10000, 0, 255);
14956 break;
14957 }
14958 case COMBODLIFTLIGHTRAD:
14959 {
14960 if (!checkComboRef()) break;
14961
14962 combobuf[GET_REF(combodataref)].lift_weap_data.light_rads[WPNSPR_BASE] = vbound(value/10000, 0, 255);
14963 break;
14964 }
14965 case COMBODLIFTLIGHTSHAPE:
14966 {
14967 if (!checkComboRef()) break;
14968
14969 combobuf[GET_REF(combodataref)].lift_weap_data.glow_shape = vbound(value/10000, 0, 2);
14970 break;
14971 }
14972 case COMBODLIFTWEAPONITEM:
14973 {
14974 if (!checkComboRef()) break;
14975
14976 combobuf[GET_REF(combodataref)].lift_parent_item = vbound(value/10000, 0, 255);
14977 break;
14978 }
14979 case COMBODTRIGGERLSTATE:
14980 {
14981 if (!checkComboRef()) break;
14982
14983 if(auto* trig = get_first_combo_trigger())
14984 trig->trig_lstate = vbound(value/10000, 0, 31);
14985 break;
14986 }
14987 case COMBODTRIGGERGSTATE:
14988 {
14989 if (!checkComboRef()) break;
14990
14991 if(auto* trig = get_first_combo_trigger())
14992 trig->trig_gstate = vbound(value/10000, 0, 255);
14993 break;
14994 }
14995 case COMBODTRIGGERGROUP:
14996 {
14997 if (!checkComboRef()) break;
14998
14999 if(auto* trig = get_first_combo_trigger())
15000 trig->trig_group = vbound(value/10000, 0, 255);
15001 break;
15002 }
15003 case COMBODTRIGGERGROUPVAL:
15004 {
15005 if (!checkComboRef()) break;
15006
15007 if(auto* trig = get_first_combo_trigger())
15008 trig->trig_group_val = vbound(value/10000, 0, 65535);
15009 break;
15010 }
15011 case COMBODTRIGGERGTIMER:
15012 {
15013 if (!checkComboRef()) break;
15014
15015 if(auto* trig = get_first_combo_trigger())
15016 trig->trig_statetime = vbound(value/10000, 0, 214748);
15017 break;
15018 }
15019 case COMBODTRIGGERGENSCRIPT:
15020 {
15021 if (!checkComboRef()) break;
15022
15023 if(auto* trig = get_first_combo_trigger())
15024 trig->trig_genscr = vbound(value/10000, 0, 65535);
15025 break;
15026 }
15027 case COMBODTRIGGERLEVEL:
15028 {
15029 if (!checkComboRef()) break;
15030
15031 if(auto* trig = get_first_combo_trigger())
15032 trig->triggerlevel = vbound(value/10000, 0, 214747);
15033 break;
15034 }
15035 case COMBODNUMTRIGGERS:
15036 {
15037 if(checkComboRef())
15038 combobuf[GET_REF(combodataref)].triggers.resize(vbound(value / 10000, 0, MAX_COMBO_TRIGGERS));
15039 break;
15040 }
15041 case COMBODONLYGEN:
15042 {
15043 if(checkComboRef())
15044 combobuf[GET_REF(combodataref)].only_gentrig = value != 0 ? 1 : 0;
15045 break;
15046 }
15047 case COMBOD_Z_HEIGHT:
15048 {
15049 if(checkComboRef())
15050 combobuf[GET_REF(combodataref)].z_height = zslongToFix(value);
15051 break;
15052 }
15053 case COMBOD_Z_STEP_HEIGHT:
15054 {
15055 if(checkComboRef())
15056 combobuf[GET_REF(combodataref)].z_step_height = zslongToFix(zc_max(0,value));
15057 break;
15058 }
15059 case COMBOD_DIVE_UNDER_LEVEL:
15060 {
15061 if(checkComboRef())
15062 combobuf[GET_REF(combodataref)].dive_under_level = (byte)vbound(value / 10000, 0, 255);
15063 break;
15064 }
15065
15066
15067
15068
15069 //COMBOCLASS STRUCT
15070 //case COMBODNAME: //CHAR[64], STRING
15071 case COMBODBLOCKNPC: SET_COMBOCLASS_VAR_BYTE(block_enemies); break; //C
15072 case COMBODBLOCKHOLE: SET_COMBOCLASS_VAR_BYTE(block_hole); break; //C
15073 case COMBODBLOCKTRIG: SET_COMBOCLASS_VAR_BYTE(block_trigger); break; //C
15074 // Note: not used?
15075 case COMBODBLOCKWEAPON: SET_COMBOCLASS_BYTE_INDEX(block_weapon, 32); break; //C, 32 INDICES
15076 case COMBODCONVXSPEED: SET_COMBOCLASS_VAR_DWORD(conveyor_x_speed); break; //SHORT
15077 case COMBODCONVYSPEED: SET_COMBOCLASS_VAR_DWORD(conveyor_y_speed); break; //SHORT
15078 case COMBODSPAWNNPC: SET_COMBOCLASS_VAR_DWORD(create_enemy); break; //W
15079 case COMBODSPAWNNPCWHEN: SET_COMBOCLASS_VAR_BYTE(create_enemy_when); break; //C
15080 case COMBODSPAWNNPCCHANGE: SET_COMBOCLASS_VAR_INT(create_enemy_change); break; //LONG
15081 case COMBODDIRCHANGETYPE: SET_COMBOCLASS_VAR_BYTE(directional_change_type); break; //C
15082 case COMBODDISTANCECHANGETILES: SET_COMBOCLASS_VAR_INT(distance_change_tiles); break; //LONG
15083 case COMBODDIVEITEM: SET_COMBOCLASS_VAR_DWORD(dive_item); break; //SHORT
15084 case COMBODDOCK: SET_COMBOCLASS_VAR_BYTE(dock); break; //C
15085 case COMBODFAIRY: SET_COMBOCLASS_VAR_BYTE(fairy); break; //C
15086 case COMBODFFATTRCHANGE: SET_COMBOCLASS_VAR_BYTE(ff_combo_attr_change); break; //C
15087 case COMBODFOORDECOTILE: SET_COMBOCLASS_VAR_INT(foot_decorations_tile); break; //LONG
15088 case COMBODFOORDECOTYPE: SET_COMBOCLASS_VAR_BYTE(foot_decorations_type); break; //C
15089 case COMBODHOOKSHOTPOINT: SET_COMBOCLASS_VAR_BYTE(hookshot_grab_point); break; //C
15090 case COMBODLADDERPASS: SET_COMBOCLASS_VAR_BYTE(ladder_pass); break; //C
15091 case COMBODLOCKBLOCK: SET_COMBOCLASS_VAR_BYTE(lock_block_type); break; //C
15092 case COMBODLOCKBLOCKCHANGE: SET_COMBOCLASS_VAR_INT(lock_block_change); break; //LONG
15093 case COMBODMAGICMIRROR: SET_COMBOCLASS_VAR_BYTE(magic_mirror_type); break; //C
15094 case COMBODMODHPAMOUNT: SET_COMBOCLASS_VAR_DWORD(modify_hp_amount); break; //SHORT
15095 case COMBODMODHPDELAY: SET_COMBOCLASS_VAR_BYTE(modify_hp_delay); break; //C
15096 case COMBODMODHPTYPE: SET_COMBOCLASS_VAR_BYTE(modify_hp_type); break; //C
15097 case COMBODNMODMPAMOUNT: SET_COMBOCLASS_VAR_DWORD(modify_mp_amount); break; //SHORT
15098 case COMBODMODMPDELAY: SET_COMBOCLASS_VAR_BYTE(modify_mp_delay); break; //C
15099 case COMBODMODMPTYPE: SET_COMBOCLASS_VAR_BYTE(modify_mp_type); break; //C
15100 case COMBODNOPUSHBLOCK: SET_COMBOCLASS_VAR_BYTE(no_push_blocks); break; //C
15101 case COMBODOVERHEAD: SET_COMBOCLASS_VAR_BYTE(overhead); break; //C
15102 case COMBODPLACENPC: SET_COMBOCLASS_VAR_BYTE(place_enemy); break; //C
15103 case COMBODPUSHDIR: SET_COMBOCLASS_VAR_BYTE(push_direction); break; //C
15104 case COMBODPUSHWAIT: SET_COMBOCLASS_VAR_BYTE(push_wait); break; //C
15105 case COMBODPUSHHEAVY: SET_COMBOCLASS_VAR_BYTE(push_weight); break; //C
15106 case COMBODPUSHED: SET_COMBOCLASS_VAR_BYTE(pushed); break; //C
15107 case COMBODRAFT: SET_COMBOCLASS_VAR_BYTE(raft); break; //C
15108 case COMBODRESETROOM: SET_COMBOCLASS_VAR_BYTE(reset_room); break; //C
15109 case COMBODSAVEPOINTTYPE: SET_COMBOCLASS_VAR_BYTE(save_point_type); break; //C
15110 case COMBODSCREENFREEZETYPE: SET_COMBOCLASS_VAR_BYTE(screen_freeze_type); break; //C
15111 case COMBODSECRETCOMBO: SET_COMBOCLASS_VAR_BYTE(secret_combo); break; //C
15112 case COMBODSINGULAR: SET_COMBOCLASS_VAR_BYTE(singular); break; //C
15113 case COMBODSLOWWALK: SET_COMBOCLASS_VAR_BYTE(slow_movement); break; //C
15114 case COMBODSTATUETYPE: SET_COMBOCLASS_VAR_BYTE(statue_type); break; //C
15115 case COMBODSTEPTYPE: SET_COMBOCLASS_VAR_BYTE(step_type); break; //C
15116 case COMBODSTEPCHANGEINTO: SET_COMBOCLASS_VAR_INT(step_change_to); break; //LONG
15117 case COMBODSTRIKEWEAPONS: SET_COMBOCLASS_BYTE_INDEX(strike_weapons, 32); break; //BYTE, 32 INDICES.
15118 case COMBODSTRIKEREMNANTS: SET_COMBOCLASS_VAR_INT(strike_remnants); break; //LONG
15119 case COMBODSTRIKEREMNANTSTYPE: SET_COMBOCLASS_VAR_BYTE(strike_remnants_type); break; //C
15120 case COMBODSTRIKECHANGE: SET_COMBOCLASS_VAR_INT(strike_change); break; //LONG
15121 case COMBODSTRIKEITEM: SET_COMBOCLASS_VAR_DWORD(strike_item); break; //SHORT
15122 case COMBODTOUCHITEM: SET_COMBOCLASS_VAR_DWORD(touch_item); break; //SHORT
15123 case COMBODTOUCHSTAIRS: SET_COMBOCLASS_VAR_BYTE(touch_stairs); break; //C
15124 case COMBODTRIGGERTYPE: SET_COMBOCLASS_VAR_BYTE(trigger_type); break; //C
15125 case COMBODTRIGGERSENS: SET_COMBOCLASS_VAR_BYTE(trigger_sensitive); break; //C
15126 case COMBODWARPTYPE: SET_COMBOCLASS_VAR_BYTE(warp_type); break; //C
15127 case COMBODWARPSENS: SET_COMBOCLASS_VAR_BYTE(warp_sensitive); break; //C
15128 case COMBODWARPDIRECT: SET_COMBOCLASS_VAR_BYTE(warp_direct); break; //C
15129 case COMBODWARPLOCATION: SET_COMBOCLASS_VAR_BYTE(warp_location); break; //C
15130 case COMBODWATER: SET_COMBOCLASS_VAR_BYTE(water); break; //C
15131 case COMBODWHISTLE: SET_COMBOCLASS_VAR_BYTE(whistle); break; //C
15132 case COMBODWINGAME: SET_COMBOCLASS_VAR_BYTE(win_game); break; //C
15133 case COMBODBLOCKWPNLEVEL: SET_COMBOCLASS_VAR_BYTE(block_weapon_lvl); break; //C
15134
15135
15136
15137 ///----------------------------------------------------------------------------------------------------//
15138 case CMBTRIGWPNLEVEL:
15139 {
15140 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15141 {
15142 trig->triggerlevel = vbound(value/10000, 0, 214748);
15143 }
15144 break;
15145 }
15146 case CMBTRIGREQITEM:
15147 {
15148 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15149 {
15150 trig->triggeritem = vbound(value/10000, 0, MAXITEMS-1);
15151 }
15152 break;
15153 }
15154 case CMBTRIGTIMER:
15155 {
15156 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15157 {
15158 trig->trigtimer = vbound(value/10000, 0, 65535);
15159 }
15160 break;
15161 }
15162 case CMBTRIGSFX:
15163 {
15164 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15165 {
15166 trig->trigsfx = vbound(value/10000, 0, 255);
15167 }
15168 break;
15169 }
15170 case CMBTRIGCHANGECMB:
15171 {
15172 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15173 {
15174 trig->trigchange = value/10000;
15175 }
15176 break;
15177 }
15178 case CMBTRIGCSETCHANGE:
15179 {
15180 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15181 {
15182 trig->trigcschange = vbound(value/10000, -128, 127);
15183 }
15184 break;
15185 }
15186 case CMBTRIGPROX:
15187 {
15188 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15189 {
15190 trig->trigprox = vbound(value/10000, 0, 65535);
15191 }
15192 break;
15193 }
15194 case CMBTRIGLIGHTBEAM:
15195 {
15196 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15197 {
15198 trig->triglbeam = vbound(value/10000,0,32);
15199 }
15200 break;
15201 }
15202 case CMBTRIGCTR:
15203 {
15204 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15205 {
15206 trig->trigctr = vbound(value/10000, sscMIN, MAX_COUNTERS-1);
15207 }
15208 break;
15209 }
15210 case CMBTRIGCTRAMNT:
15211 {
15212 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15213 {
15214 trig->trigctramnt = vbound(value/10000, -65535, 65535);
15215 }
15216 break;
15217 }
15218 case CMBTRIGCOOLDOWN:
15219 {
15220 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15221 {
15222 trig->trigcooldown = vbound(value/10000, 0, 255);
15223 }
15224 break;
15225 }
15226 case CMBTRIGCOPYCAT:
15227 {
15228 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15229 {
15230 trig->trigcopycat = vbound(value/10000, 0, 255);
15231 }
15232 break;
15233 }
15234 case CMBTRIGITEMPICKUP:
15235 {
15236 const int32_t allowed_pflags = ipHOLDUP | ipTIMER | ipSECRETS | ipCANGRAB;
15237 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15238 {
15239 trig->spawnip = (value/10000)&allowed_pflags;
15240 }
15241 break;
15242 }
15243 case CMBTRIGEXSTATE:
15244 {
15245 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15246 {
15247 trig->exstate = vbound(value/10000, -1, 31);
15248 }
15249 break;
15250 }
15251 case CMBTRIGEXDOORDIR:
15252 {
15253 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15254 {
15255 trig->exdoor_dir = vbound(value/10000, -1, 3);
15256 }
15257 break;
15258 }
15259 case CMBTRIGEXDOORIND:
15260 {
15261 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15262 {
15263 trig->exdoor_ind = vbound(value/10000, 0, 7);
15264 }
15265 break;
15266 }
15267 case CMBTRIGSPAWNENEMY:
15268 {
15269 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15270 {
15271 trig->spawnenemy = vbound(value/10000, 0, 511);
15272 }
15273 break;
15274 }
15275 case CMBTRIGSPAWNITEM:
15276 {
15277 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15278 {
15279 trig->spawnitem = vbound(value/10000, -255, 255);
15280 }
15281 break;
15282 }
15283 case CMBTRIGLSTATE:
15284 {
15285 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15286 {
15287 trig->trig_lstate = vbound(value/10000, 0, 31);
15288 }
15289 break;
15290 }
15291 case CMBTRIGGSTATE:
15292 {
15293 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15294 {
15295 trig->trig_gstate = vbound(value/10000, 0, 255);
15296 }
15297 break;
15298 }
15299 case CMBTRIGGTIMER:
15300 {
15301 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15302 {
15303 trig->trig_statetime = vbound(value/10000, 0, 214748);
15304 }
15305 break;
15306 }
15307 case CMBTRIGGENSCRIPT:
15308 {
15309 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15310 {
15311 trig->trig_genscr = vbound(value/10000, 0, 65535);
15312 }
15313 break;
15314 }
15315 case CMBTRIGGROUP:
15316 {
15317 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15318 {
15319 trig->trig_group = vbound(value/10000, 0, 255);
15320 }
15321 break;
15322 }
15323 case CMBTRIGGROUPVAL:
15324 {
15325 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15326 {
15327 trig->trig_group_val = vbound(value/10000, 0, 65535);
15328 }
15329 break;
15330 }
15331 case CMBTRIGLITEMS:
15332 {
15333 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15334 {
15335 trig->trig_levelitems = (value/10000) & LI_ALL;
15336 }
15337 break;
15338 }
15339 case CMBTRIGDMAPLVL:
15340 {
15341 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15342 {
15343 trig->trigdmlevel = vbound(value/10000, -1, MAXLEVELS-1);
15344 }
15345 break;
15346 }
15347 case CMBTRIGREQSTATEMAP:
15348 {
15349 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15350 {
15351 trig->trigstatemap = vbound(value/10000, 0, map_count);
15352 }
15353 break;
15354 }
15355 case CMBTRIGREQSTATESCREEN:
15356 {
15357 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15358 {
15359 trig->trigstatescreen = vbound(value/10000, 0, MAPSCRSNORMAL-1);
15360 }
15361 break;
15362 }
15363 case CMBTRIGTINTR:
15364 {
15365 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15366 {
15367 trig->trigtint[0] = scripting_write_pal_color(vbound(value/10000, -scripting_max_color_val, scripting_max_color_val));
15368 }
15369 break;
15370 }
15371 case CMBTRIGTINTG:
15372 {
15373 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15374 {
15375 trig->trigtint[1] = scripting_write_pal_color(vbound(value/10000, -scripting_max_color_val, scripting_max_color_val));
15376 }
15377 break;
15378 }
15379 case CMBTRIGTINTB:
15380 {
15381 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15382 {
15383 trig->trigtint[2] = scripting_write_pal_color(vbound(value/10000, -scripting_max_color_val, scripting_max_color_val));
15384 }
15385 break;
15386 }
15387 case CMBTRIGLVLPAL:
15388 {
15389 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15390 {
15391 trig->triglvlpalette = vbound(value/10000, -1, 512);
15392 }
15393 break;
15394 }
15395 case CMBTRIGBOSSPAL:
15396 {
15397 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15398 {
15399 trig->trigbosspalette = vbound(value/10000, -1, 29);
15400 }
15401 break;
15402 }
15403 case CMBTRIGQUAKETIME:
15404 {
15405 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15406 {
15407 trig->trigquaketime = zc_max(value/10000, -1);
15408 }
15409 break;
15410 }
15411 case CMBTRIGWAVYTIME:
15412 {
15413 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15414 {
15415 trig->trigwavytime = zc_max(value/10000, -1);
15416 }
15417 break;
15418 }
15419 case CMBTRIGSWORDJINX:
15420 {
15421 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15422 {
15423 trig->trig_swjinxtime = zc_max(value/10000, -2);
15424 }
15425 break;
15426 }
15427 case CMBTRIGITEMJINX:
15428 {
15429 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15430 {
15431 trig->trig_itmjinxtime = zc_max(value/10000, -2);
15432 }
15433 break;
15434 }
15435 case CMBTRIGSHIELDJINX:
15436 {
15437 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15438 {
15439 trig->trig_shieldjinxtime = zc_max(value/10000, -2);
15440 }
15441 break;
15442 }
15443 case CMBTRIGSTUN:
15444 {
15445 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15446 {
15447 trig->trig_stuntime = zc_max(value/10000, -2);
15448 }
15449 break;
15450 }
15451 case CMBTRIGBUNNY:
15452 {
15453 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15454 {
15455 trig->trig_bunnytime = zc_max(value/10000, -2);
15456 }
15457 break;
15458 }
15459 case CMBTRIGPUSHTIME:
15460 {
15461 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15462 {
15463 trig->trig_pushtime = vbound(value/10000, 0, 255);
15464 }
15465 break;
15466 }
15467 case CMBTRIGGERPROMPTCID:
15468 {
15469 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15470 trig->prompt_cid = vbound(value/10000, 0, MAXCOMBOS-1);
15471 break;
15472 }
15473 case CMBTRIGGERPROMPTCS:
15474 {
15475 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15476 trig->prompt_cs = (value/10000)&15;
15477 break;
15478 }
15479 case CMBTRIGGERFAILPROMPTCID:
15480 {
15481 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15482 trig->fail_prompt_cid = vbound(value/10000, 0, MAXCOMBOS-1);
15483 break;
15484 }
15485 case CMBTRIGGERFAILPROMPTCS:
15486 {
15487 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15488 trig->fail_prompt_cs = (value/10000)&15;
15489 break;
15490 }
15491 case CMBTRIGGERPROMPTX:
15492 {
15493 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15494 trig->prompt_x = vbound(value/10000, -32768, 32767);
15495 break;
15496 }
15497 case CMBTRIGGERPROMPTY:
15498 {
15499 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15500 trig->prompt_y = vbound(value/10000, -32768, 32767);
15501 break;
15502 }
15503 case CMBTRIGGERTRIGSTR:
15504 {
15505 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15506 trig->trig_msgstr = vbound(value/10000, 0, msg_count-1);
15507 break;
15508 }
15509 case CMBTRIGGERFAILSTR:
15510 {
15511 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15512 trig->fail_msgstr = vbound(value/10000, 0, msg_count-1);
15513 break;
15514 }
15515 case CMBTRIGGERPLAYERBOUNCE:
15516 {
15517 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15518 trig->player_bounce = zslongToFix(value);
15519 break;
15520 }
15521 case CMBTRIGGERREQPLAYERZ:
15522 {
15523 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15524 trig->req_player_z = zslongToFix(value);
15525 break;
15526 }
15527 case CMBTRIGGERDESTHEROX:
15528 {
15529 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15530 trig->dest_player_x = zslongToFix(value);
15531 break;
15532 }
15533 case CMBTRIGGERDESTHEROY:
15534 {
15535 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15536 trig->dest_player_y = zslongToFix(value);
15537 break;
15538 }
15539 case CMBTRIGGERDESTHEROZ:
15540 {
15541 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15542 trig->dest_player_z = zslongToFix(value);
15543 break;
15544 }
15545 case CMBTRIGGERREQPLAYERJUMP:
15546 {
15547 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15548 trig->req_player_jump = zslongToFix(value);
15549 break;
15550 }
15551 case CMBTRIGGERREQPLAYERX:
15552 {
15553 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15554 trig->req_player_x = zslongToFix(value);
15555 break;
15556 }
15557 case CMBTRIGGERREQPLAYERY:
15558 {
15559 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15560 trig->req_player_y = zslongToFix(value);
15561 break;
15562 }
15563 case CMBTRIGGERFORCEPLAYERDIR:
15564 {
15565 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15566 trig->dest_player_dir = vbound(value/10000, 3, -1);
15567 break;
15568 }
15569 case CMBTRIGGERICECOMBO:
15570 {
15571 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15572 trig->force_ice_combo = vbound(value/10000, MAXCOMBOS-1, -1);
15573 break;
15574 }
15575 case CMBTRIGGERICEVX:
15576 {
15577 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15578 trig->force_ice_vx = zslongToFix(value);
15579 break;
15580 }
15581 case CMBTRIGGERICEVY:
15582 {
15583 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15584 trig->force_ice_vy = zslongToFix(value);
15585 break;
15586 }
15587 case CMBTRIGGER_GRAVITY:
15588 {
15589 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15590 trig->trig_gravity = zslongToFix(value);
15591 break;
15592 }
15593 case CMBTRIGGER_TERMINAL_VELOCITY:
15594 {
15595 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15596 trig->trig_terminal_v = zslongToFix(value);
15597 break;
15598 }
15599 ///----------------------------------------------------------------------------------------------------//
15600 //npcdata nd-> Variables
15601
15602 #define SET_NPCDATA_VAR_INT(member, str) \
15603 { \
15604 if( auto nd = checkNPCData(GET_REF(npcdataref)) ) \
15605 nd->member = vbound((value / 10000),0,214747); \
15606 } \
15607
15608 #define SET_NPCDATA_VAR_DWORD(member, str) \
15609 { \
15610 if( auto nd = checkNPCData(GET_REF(npcdataref)) ) \
15611 nd->member = vbound((value / 10000),0,32767); \
15612 } \
15613
15614 #define SET_NPCDATA_VAR_ENUM(member, str) \
15615 { \
15616 if( auto nd = checkNPCData(GET_REF(npcdataref)) ) \
15617 nd->member = (decltype(guysbuf[GET_REF(npcdataref)].member))vbound((value / 10000),0,32767); \
15618 } \
15619
15620 #define SET_NPCDATA_VAR_BYTE(member, str) \
15621 { \
15622 if( auto nd = checkNPCData(GET_REF(npcdataref)) ) \
15623 nd->member = vbound((value / 10000),0,255); \
15624 } \
15625
15626 #define SET_NPCDATA_FLAG(member, str) \
15627 { \
15628 int32_t flag = (value/10000); \
15629 if( auto nd = checkNPCData(GET_REF(npcdataref)) ) \
15630 { \
15631 if ( flag ) \
15632 { \
15633 nd->member|=flag; \
15634 } \
15635 else nd->member|= ~flag; \
15636 } \
15637 } \
15638
15639 case NPCDATATILE: SET_NPCDATA_VAR_BYTE(tile, "Tile"); break;
15640 case NPCDATAWIDTH: SET_NPCDATA_VAR_BYTE(width, "Width"); break;
15641 case NPCDATAHEIGHT: SET_NPCDATA_VAR_BYTE(height, "Height"); break;
15642 case NPCDATAFLAGS1: SET_NPCDATA_VAR_ENUM(flags, "Flags (deprecated)"); break;
15643 case NPCDATAFLAGS2: SET_NPCDATA_VAR_ENUM(flags, "Flags2 (deprecated)"); break;
15644 case NPCDATASTILE: SET_NPCDATA_VAR_BYTE(s_tile, "STile"); break;
15645 case NPCDATASWIDTH: SET_NPCDATA_VAR_BYTE(s_width, "SWidth"); break;
15646 case NPCDATASHEIGHT: SET_NPCDATA_VAR_BYTE(s_height, "SHeight"); break;
15647 case NPCDATAETILE: SET_NPCDATA_VAR_INT(e_tile, "ExTile"); break;
15648 case NPCDATAEWIDTH: SET_NPCDATA_VAR_BYTE(e_width, "ExWidth"); break;
15649 case NPCDATASCRIPT: SET_NPCDATA_VAR_BYTE(script, "Script"); break;
15650 case NPCDATAEHEIGHT: SET_NPCDATA_VAR_BYTE(e_height, "ExHeight"); break;
15651 case NPCDATAHP: SET_NPCDATA_VAR_DWORD(hp, "HP"); break;
15652 case NPCDATATYPE: SET_NPCDATA_VAR_DWORD(type, "Family"); break;
15653 case NPCDATACSET: SET_NPCDATA_VAR_DWORD(cset, "CSet"); break;
15654 case NPCDATAANIM: SET_NPCDATA_VAR_DWORD(anim, "Anim"); break;
15655 case NPCDATAEANIM: SET_NPCDATA_VAR_DWORD(e_anim, "ExAnim"); break;
15656 case NPCDATAFRAMERATE: SET_NPCDATA_VAR_DWORD(frate, "Framerate"); break;
15657 case NPCDATAEFRAMERATE: SET_NPCDATA_VAR_DWORD(e_frate, "ExFramerate"); break;
15658 case NPCDATATOUCHDAMAGE: SET_NPCDATA_VAR_DWORD(dp, "TouchDamage"); break;
15659 case NPCDATAWEAPONDAMAGE: SET_NPCDATA_VAR_DWORD(wdp, "WeaponDamage"); break;
15660 case NPCDATAWEAPON: SET_NPCDATA_VAR_DWORD(weapon, "Weapon"); break;
15661 case NPCDATARANDOM: SET_NPCDATA_VAR_DWORD(rate, "Random"); break;
15662 case NPCDATAHALT: SET_NPCDATA_VAR_DWORD(hrate, "Haltrate"); break;
15663 case NPCDATASTEP: SET_NPCDATA_VAR_DWORD(step, "Step"); break;
15664 case NPCDATAHOMING: SET_NPCDATA_VAR_DWORD(homing, "Homing"); break;
15665 case NPCDATAHUNGER: SET_NPCDATA_VAR_DWORD(grumble, "Hunger"); break;
15666 case NPCDATADROPSET: SET_NPCDATA_VAR_DWORD(item_set, "Dropset"); break;
15667 case NPCDATABGSFX: SET_NPCDATA_VAR_DWORD(bgsfx, "BGSFX"); break;
15668 case NPCDATADEATHSFX: SET_NPCDATA_VAR_BYTE(deadsfx, "DeathSFX"); break;
15669 case NPCDATAHITSFX: SET_NPCDATA_VAR_BYTE(hitsfx, "HitSFX"); break;
15670 case NPCDATAXOFS: SET_NPCDATA_VAR_INT(xofs, "DrawXOffset"); break;
15671 case NPCDATAYOFS: SET_NPCDATA_VAR_INT(yofs, "DrawYOffset"); break;
15672 case NPCDATAZOFS: SET_NPCDATA_VAR_INT(zofs, "DrawZOffset"); break;
15673 case NPCDATAHXOFS: SET_NPCDATA_VAR_INT(hxofs, "HitXOffset"); break;
15674 case NPCDATAHYOFS: SET_NPCDATA_VAR_INT(hyofs, "HitYOffset"); break;
15675 case NPCDATAHITWIDTH: SET_NPCDATA_VAR_INT(hxsz, "HitWidth"); break;
15676 case NPCDATAHITHEIGHT: SET_NPCDATA_VAR_INT(hysz, "HitHeight"); break;
15677 case NPCDATAHITZ: SET_NPCDATA_VAR_INT(hzsz, "HitZHeight"); break;
15678 case NPCDATATILEWIDTH: SET_NPCDATA_VAR_INT(txsz, "TileWidth"); break;
15679 case NPCDATATILEHEIGHT: SET_NPCDATA_VAR_INT(tysz, "TileHeight"); break;
15680 case NPCDATAWPNSPRITE: SET_NPCDATA_VAR_INT(wpnsprite, "WeaponSprite"); break;
15681 case NPCDATAWEAPONSCRIPT:
15682 {
15683 if(checkNPCDataRef())
15684 guysbuf[GET_REF(npcdataref)].weap_data.script = vbound((value / 10000),0,214747);
15685 break;
15686 }
15687 case NPCDATASIZEFLAG: SET_NPCDATA_VAR_INT(SIZEflags, "SizeFlags"); break;
15688
15689 case NPCDATAFROZENTILE: SET_NPCDATA_VAR_INT(frozentile, "FrozenTile"); break;
15690 case NPCDATAFROZENCSET: SET_NPCDATA_VAR_INT(frozencset, "FrozenCSet"); break;
15691 case NPCDATAFIRESFX: SET_NPCDATA_VAR_BYTE(firesfx, "WeaponSFX"); break;
15692
15693 case NPCDSHADOWSPR:
15694 {
15695 if (checkNPCDataRef())
15696 guysbuf[GET_REF(npcdataref)].spr_shadow = vbound(value/10000, 0, 255);
15697 break;
15698 }
15699 case NPCDSPAWNSPR:
15700 {
15701 if (checkNPCDataRef())
15702 guysbuf[GET_REF(npcdataref)].spr_spawn = vbound(value/10000, 0, 255);
15703 break;
15704 }
15705 case NPCDDEATHSPR:
15706 {
15707 if (checkNPCDataRef())
15708 guysbuf[GET_REF(npcdataref)].spr_death = vbound(value/10000, 0, 255);
15709 break;
15710 }
15711
15712
15713 ///----------------------------------------------------------------------------------------------------//
15714 //Dropset Variables
15715
15716 case DROPSETNULLCHANCE:
15717 {
15718 if(ri->dropsetdataref > MAXITEMDROPSETS)
15719 {
15720 Z_scripterrlog("Invalid dropset pointer %d\n", ri->dropsetdataref);
15721 break;
15722 }
15723 item_drop_sets[GET_REF(dropsetdataref)].chance[0] = vbound((value / 10000),0,32767);
15724 break;
15725 }
15726
15727 ///----------------------------------------------------------------------------------------------------//
15728 //Audio Variables
15729
15730 case AUDIOPAN:
15731 {
15732 if ( !(FFCore.coreflags&FFCORE_SCRIPTED_PANSTYLE) )
15733 {
15734 FFCore.usr_panstyle = FFScript::do_getSFX_pan();
15735 FFCore.SetFFEngineFlag(FFCORE_SCRIPTED_PANSTYLE,true);
15736 }
15737 FFScript::do_setSFX_pan(value/10000);
15738 break;
15739 }
15740
15741 ///----------------------------------------------------------------------------------------------------//
15742 //Graphics->
15743
15744 case NUMDRAWS:
15745 break;
15746
15747 case MAXDRAWS: break;
15748
15749 ///----------------------------------------------------------------------------------------------------//
15750 //Misc./Internal
15751 case SP:
15752 ri->sp = value / 10000;
15753 break;
15754
15755 case SP2:
15756 ri->sp = value;
15757 break;
15758
15759 case PC:
15760 ri->pc = value;
15761 break;
15762
15763 case SWITCHKEY:
15764 ri->switchkey = value;
15765 break;
15766
15767 case SCRIPTRAM:
15768 case GLOBALRAM:
15769 531793831 ArrayH::setElement(GET_D(rINDEX), GET_D(rINDEX2) / 10000, value);
15770 531793831 break;
15771
15772 case SCRIPTRAMD:
15773 case GLOBALRAMD:
15774 ArrayH::setElement(GET_D(rINDEX), 0, value);
15775 break;
15776
15777 case REFFFC:
15778
2/2
✓ Branch 0 taken 6428643 times.
✓ Branch 1 taken 639949480 times.
646378123 ri->ffcref = ZScriptVersion::ffcRefIsSpriteId() ? value : value / 10000;
15779 646378123 break;
15780
15781 case REFITEM:
15782 2240371 ri->itemref = value;
15783 2240371 break;
15784
15785 case REFITEMDATA:
15786 59236618 ri->itemdataref = value;
15787 59236618 break;
15788
15789 case REFLWPN:
15790 12785291 ri->lwpnref = value;
15791 12785291 break;
15792
15793 case REFEWPN:
15794 48396679 ri->ewpnref = value;
15795 48396679 break;
15796
15797 case REFNPC:
15798 169200085 ri->npcref = value;
15799 169200085 break;
15800
15801 case REFSPRITE:
15802 109290683 ri->spriteref = value;
15803 109290683 break;
15804
15805 132051524 case REFMAPDATA: ri->mapdataref = value; break;
15806 case REFSCREEN: ri->screenref = value; break;
15807 12299117 case REFCOMBODATA: ri->combodataref = value; break;
15808 case REFCOMBOTRIGGER: ri->combotriggerref = value; break;
15809 22412 case REFSPRITEDATA: ri->spritedataref = value; break;
15810 412757 case REFBITMAP: ri->bitmapref = value; break;
15811 2 case REFNPCDATA: ri->npcdataref = value; break;
15812
15813 979359 case REFDMAPDATA: ri->dmapdataref = value; break;
15814 case REFSHOPDATA: ri->shopdataref = value; break;
15815 220 case REFMSGDATA: ri->msgdataref = value; break;
15816
15817
15818 10 case REFDROPSETDATA: ri->dropsetdataref = value; break;
15819 case REFBOTTLETYPE: ri->bottletyperef = value; break;
15820 case REFBOTTLESHOP: ri->bottleshopref = value; break;
15821 10426780 case REFGENERICDATA: ri->genericdataref = value; break;
15822 284 case REFFILE: ri->fileref = value; break;
15823 case REFDIRECTORY: ri->directoryref = value; break;
15824 case REFSTACK: ri->stackref = value; break;
15825 109743 case REFSUBSCREENDATA: ri->subscreendataref = value; break;
15826 20806 case REFSUBSCREENPAGE: ri->subscreenpageref = value; break;
15827 103742 case REFSUBSCREENWIDG: ri->subscreenwidgref = value; break;
15828 521996 case REFRNG: ri->rngref = value; break;
15829 case REFWEBSOCKET: ri->websocketref = value; break;
15830 193072 case CLASS_THISKEY: ri->thiskey = value; break;
15831 1156 case CLASS_THISKEY2: ri->thiskey2 = value; break;
15832 7263 case REFPALDATA: ri->paldataref = value; break;
15833 case REFSAVEMENU: ri->savemenuref = value; break;
15834
15835 //-------------------------------------------------------------------------------------------------
15836
15837 case GENDATARUNNING:
15838 {
15839
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 139 times.
139 if(user_genscript* scr = checkGenericScr(GET_REF(genericdataref)))
15840 {
15841
1/2
✓ Branch 0 taken 139 times.
✗ Branch 1 not taken.
139 if(value)
15842 139 scr->launch();
15843 else scr->quit();
15844 139 }
15845 139 break;
15846 }
15847 case GENDATASIZE:
15848 {
15849
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 67 times.
67 if(user_genscript* scr = checkGenericScr(GET_REF(genericdataref)))
15850 {
15851 67 scr->dataResize(value/10000);
15852 67 }
15853 67 break;
15854 }
15855
15856 //----------------------------------------------------------------------------------------------------//
15857
15858 case PORTALX:
15859 {
15860 if(portal* p = checkPortal(GET_REF(portalref)))
15861 p->x = zslongToFix(value);
15862 break;
15863 }
15864 case PORTALY:
15865 {
15866 if(portal* p = checkPortal(GET_REF(portalref)))
15867 p->y = zslongToFix(value);
15868 break;
15869 }
15870 case PORTALDMAP:
15871 {
15872 if(portal* p = checkPortal(GET_REF(portalref)))
15873 p->destdmap = vbound(value/10000,-1,MAXDMAPS-1);
15874 break;
15875 }
15876 case PORTALSCREEN:
15877 {
15878 if(portal* p = checkPortal(GET_REF(portalref)))
15879 p->destscr = vbound(value/10000,0,255);
15880 break;
15881 }
15882 case PORTALACLK:
15883 {
15884 if(portal* p = checkPortal(GET_REF(portalref)))
15885 p->aclk = vbound(value/10000, 0, 9999);
15886 break;
15887 }
15888 case PORTALAFRM:
15889 {
15890 if(portal* p = checkPortal(GET_REF(portalref)))
15891 p->aframe = vbound(value/10000, 0, 9999);
15892 break;
15893 }
15894 case PORTALOTILE:
15895 {
15896 if(portal* p = checkPortal(GET_REF(portalref)))
15897 p->o_tile = vbound(value/10000, 0, NEWMAXTILES-1);
15898 break;
15899 }
15900 case PORTALASPD:
15901 {
15902 if(portal* p = checkPortal(GET_REF(portalref)))
15903 p->aspd = vbound(value/10000, 0, 9999);
15904 break;
15905 }
15906 case PORTALFRAMES:
15907 {
15908 if(portal* p = checkPortal(GET_REF(portalref)))
15909 p->frames = vbound(value/10000, 0, 9999);
15910 break;
15911 }
15912 case PORTALSAVED:
15913 {
15914 if(ri->portalref < 0 || value < 0) break;
15915 if(portal* p = checkPortal(GET_REF(portalref)))
15916 {
15917 if(!value)
15918 p->saved_data = 0;
15919 else if(savedportal* sp = checkSavedPortal(value))
15920 p->saved_data = sp->getUID();
15921 }
15922 break;
15923 }
15924 case PORTALCLOSEDIS:
15925 {
15926 if(portal* p = checkPortal(GET_REF(portalref)))
15927 p->prox_active = value==0; //Inverted
15928 break;
15929 }
15930 case REFPORTAL:
15931 {
15932 ri->portalref = value;
15933 break;
15934 }
15935 case REFSAVPORTAL:
15936 {
15937 ri->savportalref = value;
15938 break;
15939 }
15940 case PORTALWARPSFX:
15941 {
15942 if(portal* p = checkPortal(GET_REF(portalref)))
15943 p->wsfx = vbound(value/10000,0,255);
15944 break;
15945 }
15946 case PORTALWARPVFX:
15947 {
15948 if(portal* p = checkPortal(GET_REF(portalref)))
15949 p->weffect = vbound(value/10000,0,255);
15950 break;
15951 }
15952 case SAVEDPORTALX:
15953 {
15954 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
15955 p->x = value;
15956 break;
15957 }
15958 case SAVEDPORTALY:
15959 {
15960 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
15961 p->y = value;
15962 break;
15963 }
15964 case SAVEDPORTALSRCDMAP:
15965 {
15966 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
15967 p->srcdmap = vbound(value/10000, -1, MAXDMAPS-1);
15968 break;
15969 }
15970 case SAVEDPORTALDESTDMAP:
15971 {
15972 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
15973 p->destdmap = vbound(value/10000, -1, MAXDMAPS-1);
15974 break;
15975 }
15976 case SAVEDPORTALSRCSCREEN:
15977 {
15978 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
15979 p->srcscr = vbound(value/10000,0,255);
15980 break;
15981 }
15982 case SAVEDPORTALDSTSCREEN:
15983 {
15984 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
15985 p->destscr = vbound(value/10000,0,255);
15986 break;
15987 }
15988 case SAVEDPORTALWARPSFX:
15989 {
15990 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
15991 p->sfx = vbound(value/10000,0,255);
15992 break;
15993 }
15994 case SAVEDPORTALWARPVFX:
15995 {
15996 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
15997 p->warpfx = vbound(value/10000,0,255);
15998 break;
15999 }
16000 case SAVEDPORTALSPRITE:
16001 {
16002 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
16003 p->spr = vbound(value/10000,0,255);
16004 break;
16005 }
16006 case SAVEDPORTALPORTAL:
16007 {
16008 if(ri->savportalref < 0 || value < 0) break;
16009 if(savedportal* sp = checkSavedPortal(GET_REF(savportalref)))
16010 {
16011 int32_t id = getPortalFromSaved(sp);
16012 if(id == value) break; //no change
16013 portal* p = checkPortal(value);
16014 if(p)
16015 {
16016 p->saved_data = sp->getUID();
16017 if(id > 0)
16018 {
16019 portal* p = checkPortal(id);
16020 p->saved_data = 0;
16021 }
16022 }
16023 }
16024 break;
16025 }
16026
16027 case GAMENUMASUB:
16028 {
16029 if(value >= 0)
16030 {
16031 size_t sz = vbound(value/10000, 0, 256);
16032 while(subscreens_active.size() < sz)
16033 {
16034 auto& sub = subscreens_active.emplace_back();
16035 sub.sub_type = sstACTIVE;
16036 }
16037 while(subscreens_active.size() > sz)
16038 subscreens_active.pop_back();
16039 }
16040 break;
16041 }
16042 case GAMENUMPSUB:
16043 {
16044 if(value >= 0)
16045 {
16046 size_t sz = vbound(value/10000, 0, 256);
16047 while(subscreens_passive.size() < sz)
16048 {
16049 auto& sub = subscreens_passive.emplace_back();
16050 sub.sub_type = sstPASSIVE;
16051 }
16052 while(subscreens_passive.size() > sz)
16053 subscreens_passive.pop_back();
16054 }
16055 break;
16056 }
16057 case GAMENUMOSUB:
16058 {
16059 if(value >= 0)
16060 {
16061 size_t sz = vbound(value/10000, 0, 256);
16062 while(subscreens_overlay.size() < sz)
16063 {
16064 auto& sub = subscreens_overlay.emplace_back();
16065 sub.sub_type = sstOVERLAY;
16066 }
16067 while(subscreens_overlay.size() > sz)
16068 subscreens_overlay.pop_back();
16069 }
16070 break;
16071 }
16072 case GAMENUMMSUB:
16073 {
16074 if(value >= 0)
16075 {
16076 size_t sz = vbound(value/10000, 0, 256);
16077 while(subscreens_map.size() < sz)
16078 {
16079 auto& sub = subscreens_map.emplace_back();
16080 sub.sub_type = sstMAP;
16081 }
16082 while(subscreens_map.size() > sz)
16083 subscreens_map.pop_back();
16084 }
16085 break;
16086 }
16087 ///----------------------------------------------------------------------------------------------------//
16088
16089 case SUBDATACURPG:
16090 {
16091
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
3 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref)))
16092
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if(sub->sub_type == sstACTIVE || sub->sub_type == sstMAP)
16093 3 sub->curpage = vbound(value/10000,0,sub->pages.size()-1);
16094 3 break;
16095 }
16096 case SUBDATANUMPG:
16097 {
16098 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref)))
16099 if((sub->sub_type == sstACTIVE || sub->sub_type == sstMAP) && value >= 10000)
16100 {
16101 size_t sz = value/10000;
16102 while(sub->pages.size() < sz)
16103 if(!sub->add_page(MAX_SUBSCR_PAGES))
16104 break;
16105 while(sub->pages.size() > sz)
16106 sub->delete_page(sub->pages.size()-1);
16107 }
16108 break;
16109 }
16110 case SUBDATATYPE: break; //READONLY
16111 ///---- ACTIVE SUBSCREENS ONLY
16112 case SUBDATACURSORPOS:
16113 {
16114 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16115 {
16116 SubscrPage& pg = sub->cur_page();
16117 //Should this be sanity checked? Or should nulling out
16118 // the cursor by setting it invalid be allowed? -Em
16119 pg.cursor_pos = vbound(value/10000,0,255);
16120 }
16121 break;
16122 }
16123 case SUBDATASCRIPT:
16124 {
16125 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16126 sub->script = vbound(value/10000,0,NUMSCRIPTSSUBSCREEN-1);
16127 break;
16128 }
16129
16130 case SUBDATATRANSLEFTTY:
16131 {
16132 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16133 {
16134 auto& trans = sub->trans_left;
16135 trans.type = vbound(value/10000,0,sstrMAX-1);
16136 }
16137 break;
16138 }
16139 case SUBDATATRANSLEFTSFX:
16140 {
16141 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16142 {
16143 auto& trans = sub->trans_left;
16144 trans.tr_sfx = vbound(value/10000,0,255);
16145 }
16146 break;
16147 }
16148 case SUBDATATRANSRIGHTTY:
16149 {
16150 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16151 {
16152 auto& trans = sub->trans_right;
16153 trans.type = vbound(value/10000,0,sstrMAX-1);
16154 }
16155 break;
16156 }
16157 case SUBDATATRANSRIGHTSFX:
16158 {
16159 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16160 {
16161 auto& trans = sub->trans_right;
16162 trans.tr_sfx = vbound(value/10000,0,255);
16163 }
16164 break;
16165 }
16166 case SUBDATASELECTORDSTX:
16167 {
16168 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16169 sub->selector_setting.x = vbound(value/10000,-32768,32767);
16170 break;
16171 }
16172 case SUBDATASELECTORDSTY:
16173 {
16174 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16175 sub->selector_setting.y = vbound(value/10000,-32768,32767);
16176 break;
16177 }
16178 case SUBDATASELECTORDSTW:
16179 {
16180 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16181 sub->selector_setting.w = vbound(value/10000,-32768,32767);
16182 break;
16183 }
16184 case SUBDATASELECTORDSTH:
16185 {
16186 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16187 sub->selector_setting.h = vbound(value/10000,-32768,32767);
16188 break;
16189 }
16190 ///---- CURRENTLY OPEN ACTIVE SUBSCREEN ONLY
16191 case SUBDATATRANSCLK:
16192 {
16193
3/6
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11 times.
11 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16194 {
16195
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 if(sub != CURRENT_ACTIVE_SUBSCREEN)
16196 Z_scripterrlog("'subscreendata->TransClock' is only"
16197 " valid for the current active/map subscreen!\n");
16198
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 else if(subscreen_open)
16199 {
16200 11 int val = value/10000;
16201
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(val < 0)
16202 subscrpg_clear_animation();
16203
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 else if(!subscr_pg_animating)
16204 {
16205 11 SubscrTransition tr = subscr_pg_transition;
16206 11 tr.tr_sfx = 0;
16207
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 subscrpg_animate(subscr_pg_from,subscr_pg_to,tr,*CURRENT_ACTIVE_SUBSCREEN,*CURRENT_ACTIVE_SUBSCREEN);
16208 11 subscr_pg_clk = val;
16209 11 }
16210 else subscr_pg_clk = val;
16211 11 }
16212 11 }
16213 11 break;
16214 }
16215 case SUBDATATRANSTY:
16216 {
16217
3/6
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11 times.
11 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16218 {
16219 11 auto& trans = subscr_pg_transition;
16220
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 if(sub != CURRENT_ACTIVE_SUBSCREEN)
16221 Z_scripterrlog("'subscreendata->TransType' is only"
16222 " valid for the current active/map subscreen!\n");
16223
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 else if(subscreen_open)
16224 11 trans.type = vbound(value/10000,0,sstrMAX-1);
16225 11 }
16226 11 break;
16227 }
16228 case SUBDATATRANSFROMPG:
16229 {
16230
3/6
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11 times.
11 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16231 {
16232
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 if(sub != CURRENT_ACTIVE_SUBSCREEN)
16233 Z_scripterrlog("'subscreendata->TransFromPage' is only"
16234 " valid for the current active/map subscreen!\n");
16235
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 else if(subscreen_open)
16236 11 subscr_pg_from = vbound(value/10000,0,sub->pages.size()-1);
16237 11 }
16238 11 break;
16239 }
16240 case SUBDATATRANSTOPG:
16241 {
16242
3/6
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11 times.
11 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16243 {
16244
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 if(sub != CURRENT_ACTIVE_SUBSCREEN)
16245 Z_scripterrlog("'subscreendata->TransToPage' is only"
16246 " valid for the current active/map subscreen!\n");
16247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 else if(subscreen_open)
16248 11 subscr_pg_to = vbound(value/10000,0,sub->pages.size()-1);
16249 11 }
16250 11 break;
16251 }
16252
16253 ///----------------------------------------------------------------------------------------------------//
16254 case SUBPGINDEX: break; //READ-ONLY
16255 case SUBPGNUMWIDG: break; //READ-ONLY
16256 case SUBPGSUBDATA: break; //READ-ONLY
16257 case SUBPGCURSORPOS:
16258 {
16259 if(SubscrPage* pg = checkSubPage(GET_REF(subscreenpageref)))
16260 pg->cursor_pos = vbound(value/10000,0,255);
16261 break;
16262 }
16263 ///----------------------------------------------------------------------------------------------------//
16264 ///---- ANY WIDGET TYPE
16265 case SUBWIDGTYPE: break; //READ-ONLY
16266 case SUBWIDGINDEX: break; //READ-ONLY
16267 case SUBWIDGPAGE: break; //READ-ONLY
16268 case SUBWIDGDISPITM: break; //READ-ONLY
16269 case SUBWIDGEQPITM: break; //READ-ONLY
16270 case SUBWIDGPOS:
16271 {
16272 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16273 widg->pos = vbound(value/10000,0,255);
16274 break;
16275 }
16276 case SUBWIDGX:
16277 {
16278
2/4
✓ Branch 0 taken 132 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 132 times.
✗ Branch 3 not taken.
132 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16279 132 widg->x = vbound(value/10000,-32768,32767);
16280 132 break;
16281 }
16282 case SUBWIDGY:
16283 {
16284
2/4
✓ Branch 0 taken 4247 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4247 times.
4247 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16285 4247 widg->y = vbound(value/10000,-32768,32767);
16286 4247 break;
16287 }
16288 case SUBWIDGW:
16289 {
16290 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16291 widg->w = vbound(value/10000,0,65535);
16292 break;
16293 }
16294 case SUBWIDGH:
16295 {
16296 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16297 widg->h = vbound(value/10000,0,65535);
16298 break;
16299 }
16300 case SUBWIDGREQCOUNTER:
16301 {
16302 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16303 widg->req_counter = vbound(value/10000,sscMIN,MAX_COUNTERS);
16304 break;
16305 }
16306 case SUBWIDGREQCOUNTERCOND:
16307 {
16308 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16309 widg->req_counter_cond_type = vbound(value/10000,CONDTY_NONE,CONDTY_MAX-1);
16310 break;
16311 }
16312 case SUBWIDGREQCOUNTERVAL:
16313 {
16314 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16315 widg->req_counter_val = vbound(value/10000,0,65535);
16316 break;
16317 }
16318 case SUBWIDGREQLITEMS:
16319 {
16320 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16321 widg->req_litems = vbound(value/10000,0,LI_ALL);
16322 break;
16323 }
16324 case SUBWIDGREQLITEMLEVEL:
16325 {
16326 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16327 widg->req_litem_level = vbound(value/10000,-1,MAXLEVELS);
16328 break;
16329 }
16330 case SUBWIDGREQ_LEVEL_STATE_LEVEL:
16331 {
16332 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16333 widg->req_lstate_level = vbound(value/10000,-1,MAXLEVELS);
16334 break;
16335 }
16336 case SUBWIDGREQ_SCRSTATE_MAP:
16337 {
16338 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16339 widg->req_scrstate_map = vbound(value/10000,0,map_count);
16340 break;
16341 }
16342 case SUBWIDGREQ_SCRSTATE_SCREEN:
16343 {
16344 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16345 widg->req_scrstate_scr = vbound(value/10000,-1,MAPSCRSNORMAL-1);
16346 break;
16347 }
16348 case SUBWIDGREQSCRIPTDISABLED:
16349 {
16350 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16351 widg->is_disabled = value != 0;
16352 break;
16353 }
16354 ///---- ACTIVE SUBSCREENS ONLY
16355 case SUBWIDGSELECTORDSTX:
16356 {
16357 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
16358 widg->selector_override.x = vbound(value/10000,-32768,32767);
16359 break;
16360 }
16361 case SUBWIDGSELECTORDSTY:
16362 {
16363 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
16364 widg->selector_override.y = vbound(value/10000,-32768,32767);
16365 break;
16366 }
16367 case SUBWIDGSELECTORDSTW:
16368 {
16369 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
16370 widg->selector_override.w = vbound(value/10000,-32768,32767);
16371 break;
16372 }
16373 case SUBWIDGSELECTORDSTH:
16374 {
16375 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
16376 widg->selector_override.h = vbound(value/10000,-32768,32767);
16377 break;
16378 }
16379
16380 case SUBWIDGPRESSSCRIPT:
16381 {
16382 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
16383 widg->generic_script = vbound(value/10000,0,NUMSCRIPTSGENERIC-1);
16384 break;
16385 }
16386 case SUBWIDGPGMODE:
16387 {
16388 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
16389 widg->pg_mode = vbound(value/10000,0,PGGOTO_MAX-1);
16390 break;
16391 }
16392 case SUBWIDGPGTARG:
16393 {
16394 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
16395 widg->pg_targ = vbound(value/10000,0,MAX_SUBSCR_PAGES-1);
16396 break;
16397 }
16398
16399 case SUBWIDGTRANSPGTY:
16400 {
16401 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
16402 {
16403 auto& trans = widg->pg_trans;
16404 trans.type = vbound(value/10000,0,sstrMAX-1);
16405 }
16406 break;
16407 }
16408 case SUBWIDGTRANSPGSFX:
16409 {
16410 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
16411 {
16412 auto& trans = widg->pg_trans;
16413 trans.tr_sfx = vbound(value/10000,0,255);
16414 }
16415 break;
16416 }
16417 case SUBWIDGTY_FONT:
16418 {
16419 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16420 {
16421 auto val = vbound(value/10000,0,font_max-1);
16422 auto ty = widg->getType();
16423 switch(ty)
16424 {
16425 case widgTEXT:
16426 ((SW_Text*)widg)->fontid = val;
16427 break;
16428 case widgITMCOOLDOWNTEXT:
16429 ((SW_ItemCooldownText*)widg)->fontid = val;
16430 break;
16431 case widgTEXTBOX:
16432 ((SW_TextBox*)widg)->fontid = val;
16433 break;
16434 case widgSELECTEDTEXT:
16435 ((SW_SelectedText*)widg)->fontid = val;
16436 break;
16437 case widgTIME:
16438 ((SW_Time*)widg)->fontid = val;
16439 break;
16440 case widgCOUNTER:
16441 ((SW_Counter*)widg)->fontid = val;
16442 break;
16443 case widgBTNCOUNTER:
16444 ((SW_BtnCounter*)widg)->fontid = val;
16445 break;
16446 case widgOLDCTR:
16447 ((SW_Counters*)widg)->fontid = val;
16448 break;
16449 case widgMMAPTITLE:
16450 ((SW_MMapTitle*)widg)->fontid = val;
16451 break;
16452 default:
16453 bad_subwidg_type(false, ty);
16454 break;
16455 }
16456 }
16457 break;
16458 }
16459 case SUBWIDGTY_ALIGN:
16460 {
16461 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16462 {
16463 auto val = vbound(value/10000,0,ALIGN_MAX-1);
16464 auto ty = widg->getType();
16465 switch(ty)
16466 {
16467 case widgTEXT:
16468 ((SW_Text*)widg)->align = val;
16469 break;
16470 case widgITMCOOLDOWNTEXT:
16471 ((SW_ItemCooldownText*)widg)->align = val;
16472 break;
16473 case widgTEXTBOX:
16474 ((SW_TextBox*)widg)->align = val;
16475 break;
16476 case widgSELECTEDTEXT:
16477 ((SW_SelectedText*)widg)->align = val;
16478 break;
16479 case widgTIME:
16480 ((SW_Time*)widg)->align = val;
16481 break;
16482 case widgCOUNTER:
16483 ((SW_Counter*)widg)->align = val;
16484 break;
16485 case widgBTNCOUNTER:
16486 ((SW_BtnCounter*)widg)->align = val;
16487 break;
16488 case widgMMAPTITLE:
16489 ((SW_MMapTitle*)widg)->align = val;
16490 break;
16491 default:
16492 bad_subwidg_type(false, ty);
16493 break;
16494 }
16495 }
16496 break;
16497 }
16498 case SUBWIDGTY_SHADOWTY:
16499 {
16500 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16501 {
16502 auto val = vbound(value/10000,0,sstsMAX-1);
16503 auto ty = widg->getType();
16504 switch(ty)
16505 {
16506 case widgTEXT:
16507 ((SW_Text*)widg)->shadtype = val;
16508 break;
16509 case widgITMCOOLDOWNTEXT:
16510 ((SW_ItemCooldownText*)widg)->shadtype = val;
16511 break;
16512 case widgTEXTBOX:
16513 ((SW_TextBox*)widg)->shadtype = val;
16514 break;
16515 case widgSELECTEDTEXT:
16516 ((SW_SelectedText*)widg)->shadtype = val;
16517 break;
16518 case widgTIME:
16519 ((SW_Time*)widg)->shadtype = val;
16520 break;
16521 case widgCOUNTER:
16522 ((SW_Counter*)widg)->shadtype = val;
16523 break;
16524 case widgBTNCOUNTER:
16525 ((SW_BtnCounter*)widg)->shadtype = val;
16526 break;
16527 case widgOLDCTR:
16528 ((SW_Counters*)widg)->shadtype = val;
16529 break;
16530 case widgMMAPTITLE:
16531 ((SW_MMapTitle*)widg)->shadtype = val;
16532 break;
16533 default:
16534 bad_subwidg_type(false, ty);
16535 break;
16536 }
16537 }
16538 break;
16539 }
16540 case SUBWIDGTY_COLOR_TXT:
16541 {
16542 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16543 {
16544 auto val = vbound(value/10000,MIN_SUBSCR_COLOR,MAX_SUBSCR_COLOR);
16545 auto ty = widg->getType();
16546 switch(ty)
16547 {
16548 case widgTEXT:
16549 ((SW_Text*)widg)->c_text.set_int_color(val);
16550 break;
16551 case widgITMCOOLDOWNTEXT:
16552 ((SW_ItemCooldownText*)widg)->c_text.set_int_color(val);
16553 break;
16554 case widgTEXTBOX:
16555 ((SW_TextBox*)widg)->c_text.set_int_color(val);
16556 break;
16557 case widgSELECTEDTEXT:
16558 ((SW_SelectedText*)widg)->c_text.set_int_color(val);
16559 break;
16560 case widgTIME:
16561 ((SW_Time*)widg)->c_text.set_int_color(val);
16562 break;
16563 case widgCOUNTER:
16564 ((SW_Counter*)widg)->c_text.set_int_color(val);
16565 break;
16566 case widgBTNCOUNTER:
16567 ((SW_BtnCounter*)widg)->c_text.set_int_color(val);
16568 break;
16569 case widgOLDCTR:
16570 ((SW_Counters*)widg)->c_text.set_int_color(val);
16571 break;
16572 case widgMMAPTITLE:
16573 ((SW_MMapTitle*)widg)->c_text.set_int_color(val);
16574 break;
16575 case widgMCGUFF_FRAME:
16576 ((SW_TriFrame*)widg)->c_number.set_int_color(val);
16577 break;
16578 default:
16579 bad_subwidg_type(false, ty);
16580 break;
16581 }
16582 }
16583 break;
16584 }
16585 case SUBWIDGTY_COLOR_SHD:
16586 {
16587 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16588 {
16589 auto val = vbound(value/10000,MIN_SUBSCR_COLOR,MAX_SUBSCR_COLOR);
16590 auto ty = widg->getType();
16591 switch(ty)
16592 {
16593 case widgTEXT:
16594 ((SW_Text*)widg)->c_shadow.set_int_color(val);
16595 break;
16596 case widgITMCOOLDOWNTEXT:
16597 ((SW_ItemCooldownText*)widg)->c_shadow.set_int_color(val);
16598 break;
16599 case widgTEXTBOX:
16600 ((SW_TextBox*)widg)->c_shadow.set_int_color(val);
16601 break;
16602 case widgSELECTEDTEXT:
16603 ((SW_SelectedText*)widg)->c_shadow.set_int_color(val);
16604 break;
16605 case widgTIME:
16606 ((SW_Time*)widg)->c_shadow.set_int_color(val);
16607 break;
16608 case widgCOUNTER:
16609 ((SW_Counter*)widg)->c_shadow.set_int_color(val);
16610 break;
16611 case widgBTNCOUNTER:
16612 ((SW_BtnCounter*)widg)->c_shadow.set_int_color(val);
16613 break;
16614 case widgOLDCTR:
16615 ((SW_Counters*)widg)->c_shadow.set_int_color(val);
16616 break;
16617 case widgMMAPTITLE:
16618 ((SW_MMapTitle*)widg)->c_shadow.set_int_color(val);
16619 break;
16620 default:
16621 bad_subwidg_type(false, ty);
16622 break;
16623 }
16624 }
16625 break;
16626 }
16627 case SUBWIDGTY_COLOR_BG:
16628 {
16629 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16630 {
16631 auto val = vbound(value/10000,MIN_SUBSCR_COLOR,MAX_SUBSCR_COLOR);
16632 auto ty = widg->getType();
16633 switch(ty)
16634 {
16635 case widgTEXT:
16636 ((SW_Text*)widg)->c_bg.set_int_color(val);
16637 break;
16638 case widgITMCOOLDOWNTEXT:
16639 ((SW_ItemCooldownText*)widg)->c_bg.set_int_color(val);
16640 break;
16641 case widgTEXTBOX:
16642 ((SW_TextBox*)widg)->c_bg.set_int_color(val);;
16643 break;
16644 case widgSELECTEDTEXT:
16645 ((SW_SelectedText*)widg)->c_bg.set_int_color(val);;
16646 break;
16647 case widgTIME:
16648 ((SW_Time*)widg)->c_bg.set_int_color(val);
16649 break;
16650 case widgCOUNTER:
16651 ((SW_Counter*)widg)->c_bg.set_int_color(val);
16652 break;
16653 case widgBTNCOUNTER:
16654 ((SW_BtnCounter*)widg)->c_bg.set_int_color(val);
16655 break;
16656 case widgOLDCTR:
16657 ((SW_Counters*)widg)->c_bg.set_int_color(val);
16658 break;
16659 case widgMMAPTITLE:
16660 ((SW_MMapTitle*)widg)->c_bg.set_int_color(val);
16661 break;
16662 case widgBGCOLOR:
16663 ((SW_Clear*)widg)->c_bg.set_int_color(val);
16664 break;
16665 case widgCOUNTERPERCBAR:
16666 ((SW_CounterPercentBar*)widg)->c_bg.set_int_color(val);
16667 break;
16668 default:
16669 bad_subwidg_type(false, ty);
16670 break;
16671 }
16672 }
16673 break;
16674 }
16675
16676 case SUBWIDGTY_COLOR_TXT2:
16677 {
16678 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16679 {
16680 auto val = vbound(value/10000,MIN_SUBSCR_COLOR,MAX_SUBSCR_COLOR);
16681 auto ty = widg->getType();
16682 switch(ty)
16683 {
16684 case widgCOUNTER:
16685 ((SW_Counter*)widg)->c_text2.set_int_color(val);
16686 break;
16687 case widgBTNCOUNTER:
16688 ((SW_BtnCounter*)widg)->c_text2.set_int_color(val);
16689 break;
16690 default:
16691 bad_subwidg_type(false, ty);
16692 break;
16693 }
16694 }
16695 break;
16696 }
16697 case SUBWIDGTY_COLOR_SHD2:
16698 {
16699 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16700 {
16701 auto val = vbound(value/10000,MIN_SUBSCR_COLOR,MAX_SUBSCR_COLOR);
16702 auto ty = widg->getType();
16703 switch(ty)
16704 {
16705 case widgCOUNTER:
16706 ((SW_Counter*)widg)->c_shadow2.set_int_color(val);
16707 break;
16708 case widgBTNCOUNTER:
16709 ((SW_BtnCounter*)widg)->c_shadow2.set_int_color(val);
16710 break;
16711 default:
16712 bad_subwidg_type(false, ty);
16713 break;
16714 }
16715 }
16716 break;
16717 }
16718 case SUBWIDGTY_COLOR_BG2:
16719 {
16720 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16721 {
16722 auto val = vbound(value/10000,MIN_SUBSCR_COLOR,MAX_SUBSCR_COLOR);
16723 auto ty = widg->getType();
16724 switch(ty)
16725 {
16726 case widgCOUNTER:
16727 ((SW_Counter*)widg)->c_bg2.set_int_color(val);
16728 break;
16729 case widgBTNCOUNTER:
16730 ((SW_BtnCounter*)widg)->c_bg2.set_int_color(val);
16731 break;
16732 default:
16733 bad_subwidg_type(false, ty);
16734 break;
16735 }
16736 }
16737 break;
16738 }
16739
16740 case SUBWIDGTY_COLOR_OLINE:
16741 {
16742 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16743 {
16744 auto val = vbound(value/10000,MIN_SUBSCR_COLOR,MAX_SUBSCR_COLOR);
16745 auto ty = widg->getType();
16746 switch(ty)
16747 {
16748 case widgLINE:
16749 ((SW_Line*)widg)->c_line.set_int_color(val);
16750 break;
16751 case widgRECT:
16752 ((SW_Rect*)widg)->c_outline.set_int_color(val);
16753 break;
16754 case widgMCGUFF_FRAME:
16755 ((SW_TriFrame*)widg)->c_outline.set_int_color(val);
16756 break;
16757 default:
16758 bad_subwidg_type(false, ty);
16759 break;
16760 }
16761 }
16762 break;
16763 }
16764
16765 case SUBWIDGTY_COLOR_FILL:
16766 {
16767 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16768 {
16769 auto val = vbound(value/10000,MIN_SUBSCR_COLOR,MAX_SUBSCR_COLOR);
16770 auto ty = widg->getType();
16771 switch(ty)
16772 {
16773 case widgRECT:
16774 ((SW_Rect*)widg)->c_fill.set_int_color(val);
16775 break;
16776 case widgCOUNTERPERCBAR:
16777 ((SW_CounterPercentBar*)widg)->c_fill.set_int_color(val);
16778 break;
16779 default:
16780 bad_subwidg_type(false, ty);
16781 break;
16782 }
16783 }
16784 break;
16785 }
16786 case SUBWIDGTY_BUTTON:
16787 {
16788 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16789 {
16790 auto val = vbound(value/10000,-1,3);
16791 auto ty = widg->getType();
16792 switch(ty)
16793 {
16794 case widgBTNITM:
16795 ((SW_ButtonItem*)widg)->btn = zc_max(0, val);
16796 break;
16797 case widgBTNCOUNTER:
16798 ((SW_BtnCounter*)widg)->btn = zc_max(0, val);
16799 break;
16800 case widgITMCOOLDOWNGAUGE:
16801 ((SW_ItemCooldownGauge*)widg)->button_id = val;
16802 break;
16803 case widgITMCOOLDOWNTEXT:
16804 ((SW_ItemCooldownText*)widg)->button_id = val;
16805 break;
16806 default:
16807 bad_subwidg_type(false, ty);
16808 break;
16809 }
16810 }
16811 break;
16812 }
16813 case SUBWIDGTY_MINDIG:
16814 {
16815 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16816 {
16817 auto val = vbound(value/10000,0,5);
16818 auto ty = widg->getType();
16819 switch(ty)
16820 {
16821 case widgCOUNTER:
16822 ((SW_Counter*)widg)->mindigits = val;
16823 break;
16824 case widgBTNCOUNTER:
16825 ((SW_BtnCounter*)widg)->mindigits = val;
16826 break;
16827 case widgOLDCTR:
16828 ((SW_Counters*)widg)->digits = val;
16829 break;
16830 default:
16831 bad_subwidg_type(false, ty);
16832 break;
16833 }
16834 }
16835 break;
16836 }
16837 case SUBWIDGTY_MAXDIG:
16838 {
16839 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16840 {
16841 auto val = vbound(value/10000,0,5);
16842 auto ty = widg->getType();
16843 switch(ty)
16844 {
16845 case widgCOUNTER:
16846 ((SW_Counter*)widg)->maxdigits = val;
16847 break;
16848 case widgBTNCOUNTER:
16849 ((SW_BtnCounter*)widg)->maxdigits = val;
16850 break;
16851 default:
16852 bad_subwidg_type(false, ty);
16853 break;
16854 }
16855 }
16856 break;
16857 }
16858 case SUBWIDGTY_INFITM:
16859 {
16860 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16861 {
16862 auto val = vbound(value/10000,-1,MAXITEMS-1);
16863 auto ty = widg->getType();
16864 switch(ty)
16865 {
16866 case widgCOUNTER:
16867 ((SW_Counter*)widg)->infitm = val;
16868 break;
16869 case widgOLDCTR:
16870 ((SW_Counters*)widg)->infitm = val;
16871 break;
16872 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE:
16873 ((SW_GaugePiece*)widg)->inf_item = val;
16874 break;
16875 case widgITMCOOLDOWNGAUGE:
16876 default:
16877 bad_subwidg_type(false, ty);
16878 break;
16879 }
16880 }
16881 break;
16882 }
16883 case SUBWIDGTY_INFCHAR:
16884 {
16885 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16886 {
16887 char val = vbound(value/10000,0,255);
16888 auto ty = widg->getType();
16889 switch(ty)
16890 {
16891 case widgCOUNTER:
16892 ((SW_Counter*)widg)->infchar = val;
16893 break;
16894 case widgBTNCOUNTER:
16895 ((SW_BtnCounter*)widg)->infchar = val;
16896 break;
16897 case widgOLDCTR:
16898 ((SW_Counters*)widg)->infchar = val;
16899 break;
16900 default:
16901 bad_subwidg_type(false, ty);
16902 break;
16903 }
16904 }
16905 break;
16906 }
16907 case SUBWIDGTY_COSTIND:
16908 {
16909 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16910 {
16911 auto val = vbound(value/10000,0,1);
16912 auto ty = widg->getType();
16913 switch(ty)
16914 {
16915 case widgBTNCOUNTER:
16916 ((SW_BtnCounter*)widg)->costind = val;
16917 break;
16918 default:
16919 bad_subwidg_type(false, ty);
16920 break;
16921 }
16922 }
16923 break;
16924 }
16925 case SUBWIDGTY_COLOR_PLAYER:
16926 {
16927 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16928 {
16929 auto val = vbound(value/10000,MIN_SUBSCR_COLOR,MAX_SUBSCR_COLOR);
16930 auto ty = widg->getType();
16931 switch(ty)
16932 {
16933 case widgMMAP:
16934 ((SW_MMap*)widg)->c_plr.set_int_color(val);
16935 break;
16936 case widgLMAP:
16937 ((SW_LMap*)widg)->c_plr.set_int_color(val);
16938 break;
16939 default:
16940 bad_subwidg_type(false, ty);
16941 break;
16942 }
16943 }
16944 break;
16945 }
16946 case SUBWIDGTY_COLOR_CMPBLNK:
16947 {
16948 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16949 {
16950 auto val = vbound(value/10000,MIN_SUBSCR_COLOR,MAX_SUBSCR_COLOR);
16951 auto ty = widg->getType();
16952 switch(ty)
16953 {
16954 case widgMMAP:
16955 ((SW_MMap*)widg)->c_cmp_blink.set_int_color(val);
16956 break;
16957 default:
16958 bad_subwidg_type(false, ty);
16959 break;
16960 }
16961 }
16962 break;
16963 }
16964 case SUBWIDGTY_COLOR_CMPOFF:
16965 {
16966 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16967 {
16968 auto val = vbound(value/10000,MIN_SUBSCR_COLOR,MAX_SUBSCR_COLOR);
16969 auto ty = widg->getType();
16970 switch(ty)
16971 {
16972 case widgMMAP:
16973 ((SW_MMap*)widg)->c_cmp_off.set_int_color(val);
16974 break;
16975 default:
16976 bad_subwidg_type(false, ty);
16977 break;
16978 }
16979 }
16980 break;
16981 }
16982 case SUBWIDGTY_COLOR_ROOM:
16983 {
16984 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16985 {
16986 auto val = vbound(value/10000,MIN_SUBSCR_COLOR,MAX_SUBSCR_COLOR);
16987 auto ty = widg->getType();
16988 switch(ty)
16989 {
16990 case widgLMAP:
16991 ((SW_LMap*)widg)->c_room.set_int_color(val);
16992 break;
16993 default:
16994 bad_subwidg_type(false, ty);
16995 break;
16996 }
16997 }
16998 break;
16999 }
17000 case SUBWIDGTY_ITEMCLASS:
17001 {
17002 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17003 {
17004 auto val = vbound(value/10000,0,itype_maxusable-1);
17005 auto ty = widg->getType();
17006 switch(ty)
17007 {
17008 case widgITEMSLOT:
17009 ((SW_ItemSlot*)widg)->iclass = val;
17010 break;
17011 case widgITMCOOLDOWNGAUGE:
17012 ((SW_ItemCooldownGauge*)widg)->item_class = val;
17013 break;
17014 case widgITMCOOLDOWNTEXT:
17015 ((SW_ItemCooldownText*)widg)->item_class = val;
17016 break;
17017 default:
17018 bad_subwidg_type(false, ty);
17019 break;
17020 }
17021 }
17022 break;
17023 }
17024 case SUBWIDGTY_ITEMID:
17025 {
17026 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17027 {
17028 auto val = vbound(value/10000,-1,MAXITEMS-1);
17029 auto ty = widg->getType();
17030 switch(ty)
17031 {
17032 case widgITEMSLOT:
17033 ((SW_ItemSlot*)widg)->iid = val;
17034 break;
17035 case widgITMCOOLDOWNGAUGE:
17036 ((SW_ItemCooldownGauge*)widg)->specific_item_id = val;
17037 break;
17038 case widgITMCOOLDOWNTEXT:
17039 ((SW_ItemCooldownText*)widg)->specific_item_id = val;
17040 break;
17041 default:
17042 bad_subwidg_type(false, ty);
17043 break;
17044 }
17045 }
17046 break;
17047 }
17048 case SUBWIDGTY_FRAMETILE:
17049 {
17050 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17051 {
17052 auto val = vbound(value/10000,0,NEWMAXTILES-1);
17053 auto ty = widg->getType();
17054 switch(ty)
17055 {
17056 case widgMCGUFF_FRAME:
17057 ((SW_TriFrame*)widg)->frame_tile = val;
17058 break;
17059 default:
17060 bad_subwidg_type(false, ty);
17061 break;
17062 }
17063 }
17064 break;
17065 }
17066 case SUBWIDGTY_FRAMECSET:
17067 {
17068 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17069 {
17070 auto val = vbound(value/10000,0,15);
17071 auto ty = widg->getType();
17072 switch(ty)
17073 {
17074 case widgMCGUFF_FRAME:
17075 ((SW_TriFrame*)widg)->frame_cset = val;
17076 break;
17077 default:
17078 bad_subwidg_type(false, ty);
17079 break;
17080 }
17081 }
17082 break;
17083 }
17084 case SUBWIDGTY_PIECETILE:
17085 {
17086 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17087 {
17088 auto val = vbound(value/10000,0,NEWMAXTILES-1);
17089 auto ty = widg->getType();
17090 switch(ty)
17091 {
17092 case widgMCGUFF_FRAME:
17093 ((SW_TriFrame*)widg)->piece_tile = val;
17094 break;
17095 default:
17096 bad_subwidg_type(false, ty);
17097 break;
17098 }
17099 }
17100 break;
17101 }
17102 case SUBWIDGTY_PIECECSET:
17103 {
17104 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17105 {
17106 auto val = vbound(value/10000,0,15);
17107 auto ty = widg->getType();
17108 switch(ty)
17109 {
17110 case widgMCGUFF_FRAME:
17111 ((SW_TriFrame*)widg)->piece_cset = val;
17112 break;
17113 default:
17114 bad_subwidg_type(false, ty);
17115 break;
17116 }
17117 }
17118 break;
17119 }
17120 case SUBWIDGTY_FLIP:
17121 {
17122 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17123 {
17124 auto val = vbound(value/10000,0,15);
17125 auto ty = widg->getType();
17126 switch(ty)
17127 {
17128 case widgMCGUFF:
17129 ((SW_McGuffin*)widg)->flip = val;
17130 break;
17131 case widgTILEBLOCK:
17132 ((SW_TileBlock*)widg)->flip = val;
17133 break;
17134 case widgMINITILE:
17135 ((SW_MiniTile*)widg)->flip = val;
17136 break;
17137 default:
17138 bad_subwidg_type(false, ty);
17139 break;
17140 }
17141 }
17142 break;
17143 }
17144 case SUBWIDGTY_NUMBER:
17145 {
17146 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17147 {
17148 auto val = vbound(value/10000,0,255);
17149 auto ty = widg->getType();
17150 switch(ty)
17151 {
17152 case widgMCGUFF:
17153 ((SW_McGuffin*)widg)->number = val;
17154 break;
17155 default:
17156 bad_subwidg_type(false, ty);
17157 break;
17158 }
17159 }
17160 break;
17161 }
17162 case SUBWIDGTY_FRAMES:
17163 {
17164 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17165 {
17166 auto val = vbound(value/10000,1,65535);
17167 auto ty = widg->getType();
17168 switch(ty)
17169 {
17170 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
17171 ((SW_GaugePiece*)widg)->frames = val;
17172 break;
17173 default:
17174 bad_subwidg_type(false, ty);
17175 break;
17176 }
17177 }
17178 break;
17179 }
17180 case SUBWIDGTY_SPEED:
17181 {
17182 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17183 {
17184 auto val = vbound(value/10000,1,65535);
17185 auto ty = widg->getType();
17186 switch(ty)
17187 {
17188 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
17189 ((SW_GaugePiece*)widg)->speed = val;
17190 break;
17191 default:
17192 bad_subwidg_type(false, ty);
17193 break;
17194 }
17195 }
17196 break;
17197 }
17198 case SUBWIDGTY_DELAY:
17199 {
17200 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17201 {
17202 auto val = vbound(value/10000,0,65535);
17203 auto ty = widg->getType();
17204 switch(ty)
17205 {
17206 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
17207 ((SW_GaugePiece*)widg)->delay = val;
17208 break;
17209 default:
17210 bad_subwidg_type(false, ty);
17211 break;
17212 }
17213 }
17214 break;
17215 }
17216 case SUBWIDGTY_CONTAINER:
17217 {
17218 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17219 {
17220 auto val = vbound(value/10000,0,65535);
17221 auto ty = widg->getType();
17222 switch(ty)
17223 {
17224 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
17225 ((SW_GaugePiece*)widg)->container = val;
17226 break;
17227 default:
17228 bad_subwidg_type(false, ty);
17229 break;
17230 }
17231 }
17232 break;
17233 }
17234 case SUBWIDGTY_GAUGE_WID:
17235 {
17236 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17237 {
17238 auto val = vbound(value/10000,1,32)-1;
17239 auto ty = widg->getType();
17240 switch(ty)
17241 {
17242 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
17243 ((SW_GaugePiece*)widg)->gauge_wid = val;
17244 break;
17245 default:
17246 bad_subwidg_type(false, ty);
17247 break;
17248 }
17249 }
17250 break;
17251 }
17252 case SUBWIDGTY_GAUGE_HEI:
17253 {
17254 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17255 {
17256 auto val = vbound(value/10000,1,32)-1;
17257 auto ty = widg->getType();
17258 switch(ty)
17259 {
17260 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
17261 ((SW_GaugePiece*)widg)->gauge_hei = val;
17262 break;
17263 default:
17264 bad_subwidg_type(false, ty);
17265 break;
17266 }
17267 }
17268 break;
17269 }
17270 case SUBWIDGTY_UNITS:
17271 {
17272 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17273 {
17274 auto val = vbound(value/10000,1,256);
17275 auto ty = widg->getType();
17276 switch(ty)
17277 {
17278 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
17279 ((SW_GaugePiece*)widg)->unit_per_frame = val-1;
17280 break;
17281 default:
17282 bad_subwidg_type(false, ty);
17283 break;
17284 }
17285 }
17286 break;
17287 }
17288 case SUBWIDGTY_HSPACE:
17289 {
17290 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17291 {
17292 auto val = vbound(value/10000,-128,127);
17293 auto ty = widg->getType();
17294 switch(ty)
17295 {
17296 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
17297 ((SW_GaugePiece*)widg)->hspace = val;
17298 break;
17299 default:
17300 bad_subwidg_type(false, ty);
17301 break;
17302 }
17303 }
17304 break;
17305 }
17306 case SUBWIDGTY_VSPACE:
17307 {
17308 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17309 {
17310 auto val = vbound(value/10000,-128,127);
17311 auto ty = widg->getType();
17312 switch(ty)
17313 {
17314 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
17315 ((SW_GaugePiece*)widg)->vspace = val;
17316 break;
17317 default:
17318 bad_subwidg_type(false, ty);
17319 break;
17320 }
17321 }
17322 break;
17323 }
17324 case SUBWIDGTY_GRIDX:
17325 {
17326 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17327 {
17328 auto val = vbound(value/10000,-32768,32767);
17329 auto ty = widg->getType();
17330 switch(ty)
17331 {
17332 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
17333 ((SW_GaugePiece*)widg)->grid_xoff = val;
17334 break;
17335 default:
17336 bad_subwidg_type(false, ty);
17337 break;
17338 }
17339 }
17340 break;
17341 }
17342 case SUBWIDGTY_GRIDY:
17343 {
17344 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17345 {
17346 auto val = vbound(value/10000,-32768,32767);
17347 auto ty = widg->getType();
17348 switch(ty)
17349 {
17350 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
17351 ((SW_GaugePiece*)widg)->grid_yoff = val;
17352 break;
17353 default:
17354 bad_subwidg_type(false, ty);
17355 break;
17356 }
17357 }
17358 break;
17359 }
17360 case SUBWIDGTY_ANIMVAL:
17361 {
17362 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17363 {
17364 auto val = vbound(value/10000,0,65535);
17365 auto ty = widg->getType();
17366 switch(ty)
17367 {
17368 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
17369 ((SW_GaugePiece*)widg)->anim_val = val;
17370 break;
17371 default:
17372 bad_subwidg_type(false, ty);
17373 break;
17374 }
17375 }
17376 break;
17377 }
17378 case SUBWIDGTY_SHOWDRAIN:
17379 {
17380 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17381 {
17382 auto val = vbound(value/10000,-1,32767);
17383 auto ty = widg->getType();
17384 switch(ty)
17385 {
17386 case widgMGAUGE:
17387 ((SW_MagicGaugePiece*)widg)->showdrain = val;
17388 break;
17389 default:
17390 bad_subwidg_type(false, ty);
17391 break;
17392 }
17393 }
17394 break;
17395 }
17396 case SUBWIDGTY_PERCONTAINER:
17397 {
17398 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17399 {
17400 auto val = zc_max(value/10000,1);
17401 auto ty = widg->getType();
17402 switch(ty)
17403 {
17404 case widgMISCGAUGE:
17405 ((SW_MiscGaugePiece*)widg)->per_container = val;
17406 break;
17407 case widgITMCOOLDOWNGAUGE:
17408 ((SW_ItemCooldownGauge*)widg)->per_container = val;
17409 break;
17410 default:
17411 bad_subwidg_type(false, ty);
17412 break;
17413 }
17414 }
17415 break;
17416 }
17417 case SUBWIDGTY_TOTAL:
17418 {
17419 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17420 {
17421 auto val = zc_max(value/10000,1);
17422 auto ty = widg->getType();
17423 switch(ty)
17424 {
17425 case widgITMCOOLDOWNGAUGE:
17426 ((SW_ItemCooldownGauge*)widg)->total_points = val;
17427 break;
17428 default:
17429 bad_subwidg_type(false, ty);
17430 break;
17431 }
17432 }
17433 break;
17434 }
17435 case SUBWIDGTY_TABSIZE:
17436 {
17437 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17438 {
17439 auto val = vbound(value/10000,0,255);
17440 auto ty = widg->getType();
17441 switch(ty)
17442 {
17443 case widgTEXTBOX:
17444 ((SW_TextBox*)widg)->tabsize = val;
17445 break;
17446 case widgSELECTEDTEXT:
17447 ((SW_SelectedText*)widg)->tabsize = val;
17448 break;
17449 default:
17450 bad_subwidg_type(false, ty);
17451 break;
17452 }
17453 }
17454 break;
17455 }
17456 case SUBWIDGTY_LITEMS:
17457 {
17458 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17459 {
17460 auto val = vbound(value/10000,0,255);
17461 auto ty = widg->getType();
17462 switch(ty)
17463 {
17464 case widgMMAP:
17465 ((SW_MMap*)widg)->compass_litems = val;
17466 break;
17467 default:
17468 bad_subwidg_type(false, ty);
17469 break;
17470 }
17471 }
17472 break;
17473 }
17474
17475 default:
17476 {
17477
2/2
✓ Branch 0 taken 18557755 times.
✓ Branch 1 taken 29352318 times.
47910073 if (zasm_array_supports(arg))
17478 {
17479 18557755 int ref_arg = get_register_ref_dependency(arg).value_or(0);
17480 #ifdef DEBUG_REGISTER_DEPS
17481 if (ref_arg) debug_get_ref(ref_arg);
17482 #endif
17483
2/2
✓ Branch 0 taken 10242304 times.
✓ Branch 1 taken 8315451 times.
18557755 int ref = ref_arg ? get_ref(ref_arg) : 0;
17484 18557755 zasm_array_set(arg, ref, GET_D(rINDEX) / 10000, value, script_object_type::none);
17485 18557755 }
17486 else
17487 {
17488 29352318 scripting_engine_set_register(arg, value);
17489 }
17490 }
17491 47910073 }
17492
17493 1817366488 current_zasm_register = 0;
17494 2461433812 } //end set_register
17495
17496 430 static std::map<std::string, int> name_to_slot_index_ffcmap;
17497 430 static std::map<std::string, int> name_to_slot_index_globalmap;
17498 430 static std::map<std::string, int> name_to_slot_index_genericmap;
17499 430 static std::map<std::string, int> name_to_slot_index_itemmap;
17500 430 static std::map<std::string, int> name_to_slot_index_npcmap;
17501 430 static std::map<std::string, int> name_to_slot_index_ewpnmap;
17502 430 static std::map<std::string, int> name_to_slot_index_lwpnmap;
17503 430 static std::map<std::string, int> name_to_slot_index_playermap;
17504 430 static std::map<std::string, int> name_to_slot_index_dmapmap;
17505 430 static std::map<std::string, int> name_to_slot_index_screenmap;
17506 430 static std::map<std::string, int> name_to_slot_index_itemspritemap;
17507 430 static std::map<std::string, int> name_to_slot_index_comboscriptmap;
17508 430 static std::map<std::string, int> name_to_slot_index_subscreenmap;
17509
17510 440 void script_init_name_to_slot_index_maps()
17511 {
17512 int i;
17513 #define DECL_INIT_MAP(name) \
17514 {\
17515 name_to_slot_index_##name.clear();\
17516 i = 0;\
17517 for (auto& it : name)\
17518 {\
17519 if (!name_to_slot_index_##name.contains(it.second.scriptname))\
17520 name_to_slot_index_##name[it.second.scriptname] = i;\
17521 i++;\
17522 }\
17523 }
17524
17525
4/4
✓ Branch 0 taken 224840 times.
✓ Branch 1 taken 440 times.
✓ Branch 2 taken 214298 times.
✓ Branch 3 taken 10542 times.
225280 DECL_INIT_MAP(ffcmap);
17526
4/4
✓ Branch 0 taken 3520 times.
✓ Branch 1 taken 440 times.
✓ Branch 2 taken 2014 times.
✓ Branch 3 taken 1506 times.
3960 DECL_INIT_MAP(globalmap);
17527
4/4
✓ Branch 0 taken 224840 times.
✓ Branch 1 taken 440 times.
✓ Branch 2 taken 221872 times.
✓ Branch 3 taken 2968 times.
225280 DECL_INIT_MAP(genericmap);
17528
4/4
✓ Branch 0 taken 112200 times.
✓ Branch 1 taken 440 times.
✓ Branch 2 taken 110552 times.
✓ Branch 3 taken 1648 times.
112640 DECL_INIT_MAP(itemmap);
17529
4/4
✓ Branch 0 taken 112200 times.
✓ Branch 1 taken 440 times.
✓ Branch 2 taken 111597 times.
✓ Branch 3 taken 603 times.
112640 DECL_INIT_MAP(npcmap);
17530
4/4
✓ Branch 0 taken 112200 times.
✓ Branch 1 taken 440 times.
✓ Branch 2 taken 111431 times.
✓ Branch 3 taken 769 times.
112640 DECL_INIT_MAP(ewpnmap);
17531
4/4
✓ Branch 0 taken 112200 times.
✓ Branch 1 taken 440 times.
✓ Branch 2 taken 111409 times.
✓ Branch 3 taken 791 times.
112640 DECL_INIT_MAP(lwpnmap);
17532
4/4
✓ Branch 0 taken 1760 times.
✓ Branch 1 taken 440 times.
✓ Branch 2 taken 1287 times.
✓ Branch 3 taken 473 times.
2200 DECL_INIT_MAP(playermap);
17533
4/4
✓ Branch 0 taken 112200 times.
✓ Branch 1 taken 440 times.
✓ Branch 2 taken 111241 times.
✓ Branch 3 taken 959 times.
112640 DECL_INIT_MAP(dmapmap);
17534
4/4
✓ Branch 0 taken 112200 times.
✓ Branch 1 taken 440 times.
✓ Branch 2 taken 111398 times.
✓ Branch 3 taken 802 times.
112640 DECL_INIT_MAP(screenmap);
17535
4/4
✓ Branch 0 taken 112200 times.
✓ Branch 1 taken 440 times.
✓ Branch 2 taken 111707 times.
✓ Branch 3 taken 493 times.
112640 DECL_INIT_MAP(itemspritemap);
17536
4/4
✓ Branch 0 taken 224840 times.
✓ Branch 1 taken 440 times.
✓ Branch 2 taken 224234 times.
✓ Branch 3 taken 606 times.
225280 DECL_INIT_MAP(comboscriptmap);
17537
4/4
✓ Branch 0 taken 112200 times.
✓ Branch 1 taken 440 times.
✓ Branch 2 taken 111745 times.
✓ Branch 3 taken 455 times.
112640 DECL_INIT_MAP(subscreenmap);
17538 440 }
17539
17540 10256669 static void do_get_script_index_by_name(const std::map<std::string, int>& name_to_slot_index)
17541 {
17542 10256669 int32_t arrayptr = get_register(sarg1);
17543 10256669 string name;
17544 10256669 int32_t num=-1;
17545
1/2
✓ Branch 0 taken 10256669 times.
✗ Branch 1 not taken.
10256669 ArrayH::getString(arrayptr, name, 256); // What's the limit on name length?
17546
17547
1/2
✓ Branch 0 taken 10256669 times.
✗ Branch 1 not taken.
10256669 auto it = name_to_slot_index.find(name);
17548
2/2
✓ Branch 0 taken 8430579 times.
✓ Branch 1 taken 1826090 times.
10256669 if (it != name_to_slot_index.end())
17549 1826090 num = it->second + 1;
17550
17551
1/2
✓ Branch 0 taken 10256669 times.
✗ Branch 1 not taken.
10256669 set_register(sarg1, num * 10000);
17552 10256669 }
17553
17554 ///----------------------------------------------------------------------------------------------------//
17555 // ASM Functions //
17556 ///----------------------------------------------------------------------------------------------------//
17557
17558 45955 bool check_stack(uint32_t sp)
17559 {
17560
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45955 times.
45955 if (sp >= MAX_STACK_SIZE)
17561 {
17562 log_stack_overflow_error();
17563 ri->overflow = true;
17564 return false;
17565 }
17566
17567 45955 return true;
17568 45955 }
17569
17570 2205625957 void retstack_push(int32_t val)
17571 {
17572
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2205625957 times.
2205625957 if(ri->retsp >= MAX_CALL_FRAMES)
17573 {
17574 log_call_limit_error();
17575 ri->overflow = true;
17576 return;
17577 }
17578 2205625957 (*ret_stack)[ri->retsp++] = val;
17579 2205625957 }
17580 2205579215 optional<int32_t> retstack_pop()
17581 {
17582
2/2
✓ Branch 0 taken 824 times.
✓ Branch 1 taken 2205578391 times.
2205579215 if(!ri->retsp)
17583 824 return nullopt; //return from root, so, QUIT
17584 2205578391 return (*ret_stack)[--ri->retsp];
17585 2205579215 }
17586
17587 20932243 void stack_push(int32_t val)
17588 {
17589 20932243 SH::write_stack(--ri->sp, val);
17590 20932243 }
17591 45955 void stack_push(int32_t val, size_t count)
17592 {
17593
1/2
✓ Branch 0 taken 45955 times.
✗ Branch 1 not taken.
45955 if (!check_stack(ri->sp - count))
17594 return;
17595
17596
2/2
✓ Branch 0 taken 45955 times.
✓ Branch 1 taken 245147 times.
291102 for(int q = 0; q < count; ++q)
17597 {
17598 245147 --ri->sp;
17599 245147 (*stack)[ri->sp] = val;
17600 245147 }
17601 45955 }
17602
17603 20309982 int32_t stack_pop()
17604 {
17605 20309982 const int32_t val = SH::read_stack(ri->sp);
17606 20309982 ++ri->sp;
17607 20309982 return val;
17608 }
17609 201826 int32_t stack_pop(size_t count)
17610 {
17611 201826 ri->sp += count;
17612 201826 const int32_t val = SH::read_stack(ri->sp-1);
17613 201826 return val;
17614 }
17615
17616 ///----------------------------------------------------------------------------------------------------//
17617 //Internal (to ZScript)
17618
17619 // Changing the script of the currently executing scriptable object is not supported.
17620 16995011 bool is_guarded_script_register(int reg)
17621 {
17622
2/2
✓ Branch 0 taken 16900849 times.
✓ Branch 1 taken 94162 times.
16995011 switch (reg)
17623 {
17624 case DMAPSCRIPT:
17625 case EWPNSCRIPT:
17626 case FFSCRIPT:
17627 case IDATAPSCRIPT:
17628 case IDATASCRIPT:
17629 case ITEMSPRITESCRIPT:
17630 case LWPNSCRIPT:
17631 case NPCSCRIPT:
17632 case SCREENSCRIPT:
17633 94162 return true;
17634 }
17635
17636 16900849 return false;
17637 16995011 }
17638
17639 16158036 void do_set(int reg, int value)
17640 {
17641
2/2
✓ Branch 0 taken 16067150 times.
✓ Branch 1 taken 90886 times.
16158036 if (!is_guarded_script_register(reg))
17642 {
17643 16067150 set_register(reg, value);
17644 16067150 return;
17645 }
17646
17647 90886 ScriptType whichType = curScriptType;
17648 90886 int32_t whichUID = curScriptIndex;
17649
17650 90886 bool allowed = true;
17651
8/9
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 60540 times.
✓ Branch 2 taken 18823 times.
✓ Branch 3 taken 5311 times.
✓ Branch 4 taken 1410 times.
✓ Branch 5 taken 1730 times.
✓ Branch 6 taken 3009 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 37 times.
90886 switch(whichType) //Check for objects attempting to change own script
17652 {
17653 //case ScriptType::Global:
17654
17655 case ScriptType::FFC:
17656
2/2
✓ Branch 0 taken 1958 times.
✓ Branch 1 taken 3353 times.
5311 if (reg == FFSCRIPT)
17657 {
17658
3/4
✓ Branch 0 taken 3353 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3185 times.
✓ Branch 3 taken 168 times.
3353 if (auto ffc = ResolveFFC(GET_REF(ffcref)); ffc && ffc->index == whichUID)
17659 168 allowed = false;
17660 3353 }
17661 5311 break;
17662
17663 case ScriptType::Screen:
17664
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if(reg==SCREENSCRIPT) //Only 1 screen script running at a time, no UID check needed
17665 allowed = false;
17666 26 break;
17667
17668 case ScriptType::Item:
17669 {
17670
2/2
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 1312 times.
1410 bool collect = ( ( whichUID < 1 ) || (whichUID == COLLECT_SCRIPT_ITEM_ZERO) );
17671
3/4
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 1312 times.
✓ Branch 2 taken 98 times.
✗ Branch 3 not taken.
1410 int32_t new_UID = ( collect ) ? (( whichUID != COLLECT_SCRIPT_ITEM_ZERO ) ? (whichUID * -1) : 0) : whichUID;
17672
17673
2/2
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 1312 times.
1410 if(collect)
17674 {
17675
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 98 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
98 if(reg==IDATAPSCRIPT && ri->itemdataref==new_UID)
17676 allowed = false;
17677 98 }
17678
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1312 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1312 else if(reg==IDATASCRIPT && ri->itemdataref==new_UID)
17679 allowed = false;
17680 1410 break;
17681 }
17682
17683 case ScriptType::Lwpn:
17684
3/4
✓ Branch 0 taken 60516 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 60516 times.
✗ Branch 3 not taken.
60540 if(reg==LWPNSCRIPT && ri->lwpnref==whichUID)
17685 allowed = false;
17686 60540 break;
17687
17688 case ScriptType::NPC:
17689
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1730 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1730 if(reg==NPCSCRIPT && ri->npcref==whichUID)
17690 allowed = false;
17691 1730 break;
17692
17693 case ScriptType::Ewpn:
17694
3/4
✓ Branch 0 taken 2310 times.
✓ Branch 1 taken 699 times.
✓ Branch 2 taken 2310 times.
✗ Branch 3 not taken.
3009 if(reg==EWPNSCRIPT && ri->ewpnref==whichUID)
17695 allowed = false;
17696 3009 break;
17697
17698 case ScriptType::DMap:
17699 if(reg==DMAPSCRIPT && ri->dmapdataref==whichUID)
17700 allowed = false;
17701 break;
17702
17703 case ScriptType::ItemSprite:
17704
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
37 if(reg==ITEMSPRITESCRIPT && ri->itemref==whichUID)
17705 allowed = false;
17706 37 break;
17707 }
17708
17709
2/2
✓ Branch 0 taken 90718 times.
✓ Branch 1 taken 168 times.
90886 if (!allowed)
17710 {
17711 168 Z_scripterrlog("Script attempted to change own object's script! This has been ignored.\n");
17712 168 return;
17713 }
17714
17715 90718 set_register(reg, value);
17716 16158036 }
17717
17718 16067363 void do_set_command(const bool v)
17719 {
17720 16067363 int32_t temp = SH::get_arg(sarg2, v);
17721 16067363 do_set(sarg1, temp);
17722 16067363 }
17723
17724 20932243 void do_push(const bool v)
17725 {
17726 20932243 const int32_t value = SH::get_arg(sarg1, v);
17727 20932243 stack_push(value);
17728 20932243 }
17729 5343820 void do_push_varg(const bool v)
17730 {
17731 5343820 const int32_t value = SH::get_arg(sarg1, v);
17732 5343820 zs_vargs.push_back(value);
17733 5343820 }
17734
17735 2674 void do_push_vargs(const bool v)
17736 {
17737
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2674 times.
2674 if(sarg2 < 1) return;
17738 2674 const int value = SH::get_arg(sarg1, v);
17739 2674 zs_vargs.insert(zs_vargs.end(), sarg2, value);
17740 2674 zs_vargs.push_back(value);
17741 2674 }
17742
17743 20309982 void do_pop()
17744 {
17745 20309982 set_register(sarg1, stack_pop());
17746 20309982 }
17747
17748 void do_peek()
17749 {
17750 set_register(sarg1, SH::read_stack(ri->sp));
17751 }
17752
17753 void do_peekat(const bool v)
17754 {
17755 auto offs = SH::get_arg(sarg2,v);
17756 set_register(sarg1, SH::read_stack(ri->sp+offs));
17757 }
17758
17759 void do_writeat(const bool v1, const bool v2)
17760 {
17761 auto val = SH::get_arg(sarg1,v1);
17762 auto offs = SH::get_arg(sarg2,v2);
17763 SH::write_stack(ri->sp+offs, val);
17764 }
17765
17766 201826 void do_pops() // Pop past a bunch of stuff at once. Useful for clearing the stack.
17767 {
17768 201826 set_register(sarg1, stack_pop(sarg2));
17769 201826 }
17770
17771 45955 void do_pushs(const bool v) // Push a bunch of the same thing. Useful for filling the stack.
17772 {
17773 45955 const int value = SH::get_arg(sarg1, v);
17774 45955 stack_push(value, sarg2);
17775 45955 }
17776
17777 void do_loadi()
17778 {
17779 const int32_t stackoffset = get_register(sarg2) / 10000;
17780 const int32_t value = SH::read_stack(stackoffset);
17781 set_register(sarg1, value);
17782 }
17783
17784 void do_storei()
17785 {
17786 const int32_t stackoffset = get_register(sarg2) / 10000;
17787 const int32_t value = get_register(sarg1);
17788 SH::write_stack(stackoffset, value);
17789 }
17790
17791 void do_loadd()
17792 {
17793 const int32_t stackoffset = (sarg2+GET_D(rSFRAME)) / 10000;
17794 const int32_t value = SH::read_stack(stackoffset);
17795 set_register(sarg1, value);
17796 }
17797
17798 19839774 void do_load()
17799 {
17800 19839774 const int32_t stackoffset = GET_D(rSFRAME) + sarg2;
17801 19839774 const int32_t value = SH::read_stack(stackoffset);
17802 19839774 set_register(sarg1, value);
17803 19839774 }
17804
17805 4 static void do_load_internal_array()
17806 {
17807
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 CHECK(ZScriptVersion::gc_arrays());
17808
17809 4 auto array = find_or_create_internal_script_array({sarg2, 0});
17810
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 set_register(sarg1, array ? array->id : 0);
17811 4 }
17812
17813 26 static void do_load_internal_array_ref()
17814 {
17815
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 CHECK(ZScriptVersion::gc_arrays());
17816
17817 26 int ref = get_register(sarg3);
17818 26 auto array = find_or_create_internal_script_array({sarg2, ref});
17819
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 set_register(sarg1, array ? array->id : 0);
17820 26 }
17821
17822 void do_stored(const bool v)
17823 {
17824 const int32_t stackoffset = (sarg2+GET_D(rSFRAME)) / 10000;
17825 const int32_t value = SH::get_arg(sarg1, v);
17826 SH::write_stack(stackoffset, value);
17827 }
17828
17829 3427790 void do_store(const bool v)
17830 {
17831 3427790 const int32_t stackoffset = GET_D(rSFRAME) + sarg2;
17832 3427790 const int32_t value = SH::get_arg(sarg1, v);
17833 3427790 SH::write_stack(stackoffset, value);
17834 3427790 }
17835
17836 16792614 void script_store_object(uint32_t offset, uint32_t new_id)
17837 {
17838 DCHECK(offset < MAX_STACK_SIZE);
17839
17840 // Increase, then decrease, to handle the case where a variable (holding the only reference to an object) is assigned to itself.
17841 // This is unlikely so lets not bother with a conditional that skips both ref modifications when the ids are equal.
17842 16792614 uint32_t id = SH::read_stack(offset);
17843 16792614 script_object_ref_inc(new_id);
17844
2/2
✓ Branch 0 taken 683880 times.
✓ Branch 1 taken 16108734 times.
16792614 if (ri->stackPosHasObject(offset))
17845 683880 script_object_ref_dec(id);
17846 else
17847 16108734 ri->stack_pos_is_object.insert(offset);
17848
17849 16792614 SH::write_stack(offset, new_id);
17850
17851
2/2
✓ Branch 0 taken 14596534 times.
✓ Branch 1 taken 2196080 times.
16792614 if (util::remove_if_exists(script_object_autorelease_pool, new_id))
17852 2196080 script_object_ref_dec(new_id);
17853 16792614 }
17854
17855 void do_store_object(const bool v)
17856 {
17857 const int32_t stackoffset = GET_D(rSFRAME) + sarg2;
17858 const int32_t new_id = SH::get_arg(sarg1, v);
17859 script_store_object(stackoffset, new_id);
17860 }
17861
17862 19329309 void script_remove_object_ref(int32_t offset)
17863 {
17864
1/2
✓ Branch 0 taken 19329309 times.
✗ Branch 1 not taken.
19329309 if (offset < 0 || offset >= MAX_STACK_SIZE)
17865 {
17866 assert(false);
17867 return;
17868 }
17869
17870
2/2
✓ Branch 0 taken 17685989 times.
✓ Branch 1 taken 1643320 times.
19329309 if (!ri->stackPosHasObject(offset))
17871 1643320 return;
17872
17873 17685989 uint32_t id = SH::read_stack(offset);
17874 17685989 script_object_ref_dec(id);
17875 17685989 ri->stack_pos_is_object.erase(offset);
17876 19329309 }
17877
17878 10631205 void do_comp(bool v, const bool inv = false)
17879 {
17880 10631205 bool v2 = false;
17881
1/2
✓ Branch 0 taken 10631205 times.
✗ Branch 1 not taken.
10631205 if(inv) zc_swap(v,v2);
17882 10631205 ri->cmp_op2 = SH::get_arg(sarg2, v);
17883 10631205 ri->cmp_op1 = SH::get_arg(sarg1, v2);
17884 10631205 ri->cmp_strcache = nullopt;
17885 10631205 }
17886
17887 void do_internal_strcmp()
17888 {
17889 int32_t arrayptr_a = get_register(sarg1);
17890 int32_t arrayptr_b = get_register(sarg2);
17891 string strA;
17892 string strB;
17893 ArrayH::getString(arrayptr_a, strA);
17894 ArrayH::getString(arrayptr_b, strB);
17895 ri->cmp_strcache = strcmp(strA.c_str(), strB.c_str());
17896 }
17897
17898 void do_internal_stricmp()
17899 {
17900 int32_t arrayptr_a = get_register(sarg1);
17901 int32_t arrayptr_b = get_register(sarg2);
17902 string strA;
17903 string strB;
17904 ArrayH::getString(arrayptr_a, strA);
17905 ArrayH::getString(arrayptr_b, strB);
17906 ri->cmp_strcache = stricmp(strA.c_str(), strB.c_str());
17907 }
17908
17909 1621 void do_resize_array()
17910 {
17911 1621 int32_t size = vbound(get_register(sarg2) / 10000, 0, 214748);
17912 1621 dword ptrval = get_register(sarg1);
17913 1621 ArrayManager am(ptrval);
17914 1621 am.resize(size);
17915 1621 }
17916
17917 void do_own_array(int arrindx, ScriptType scriptType, const int32_t UID)
17918 {
17919 ArrayManager am(arrindx);
17920
17921 if(am.internal())
17922 {
17923 Z_scripterrlog_force_trace("Cannot 'OwnArray()' an internal array '%d'\n", arrindx);
17924 return;
17925 }
17926 if(arrindx >= NUM_ZSCRIPT_ARRAYS && arrindx < NUM_ZSCRIPT_ARRAYS*2)
17927 {
17928 //ignore global arrays
17929 }
17930 else if(!am.invalid())
17931 {
17932 if(arrindx > 0 && arrindx < NUM_ZSCRIPT_ARRAYS)
17933 {
17934 arrayOwner[arrindx].reown(scriptType, UID);
17935 arrayOwner[arrindx].specOwned = true;
17936 }
17937 else if(arrindx < 0) //object array
17938 Z_scripterrlog_force_trace("Cannot 'OwnArray()' an object-based array '%d'\n", arrindx);
17939 }
17940 else Z_scripterrlog_force_trace("Tried to 'OwnArray()' an invalid array '%d'\n", arrindx);
17941 }
17942
17943 void do_own_array(int arrindx, sprite* spr)
17944 {
17945 ArrayManager am(arrindx);
17946
17947 if(am.internal())
17948 {
17949 Z_scripterrlog_force_trace("Cannot 'OwnArray()' an internal array '%d'\n", arrindx);
17950 return;
17951 }
17952 if(arrindx >= NUM_ZSCRIPT_ARRAYS && arrindx < NUM_ZSCRIPT_ARRAYS*2)
17953 {
17954 //ignore global arrays
17955 }
17956 else if(!am.invalid())
17957 {
17958 if(arrindx > 0 && arrindx < NUM_ZSCRIPT_ARRAYS)
17959 {
17960 arrayOwner[arrindx].reown(spr);
17961 arrayOwner[arrindx].specOwned = true;
17962 }
17963 else if(arrindx < 0) //object array
17964 Z_scripterrlog_force_trace("Cannot 'OwnArray()' an object-based array '%d'\n", arrindx);
17965 }
17966 else Z_scripterrlog_force_trace("Tried to 'OwnArray()' an invalid array '%d'\n", arrindx);
17967 }
17968
17969 void do_destroy_array()
17970 {
17971 if (ZScriptVersion::gc_arrays())
17972 {
17973 scripting_log_error_with_context("Cannot force destroy arrays in 3.0+");
17974 return;
17975 }
17976
17977 int arrindx = get_register(sarg1);
17978
17979 ArrayManager am(arrindx);
17980
17981 if(am.internal())
17982 {
17983 Z_scripterrlog_force_trace("Cannot 'DestroyArray()' an internal array '%d'\n", arrindx);
17984 return;
17985 }
17986
17987 if(arrindx >= NUM_ZSCRIPT_ARRAYS && arrindx < NUM_ZSCRIPT_ARRAYS*2)
17988 {
17989 //ignore global arrays
17990 }
17991 else if(!am.invalid())
17992 {
17993 if(arrindx > 0 && arrindx < NUM_ZSCRIPT_ARRAYS)
17994 {
17995 arrayOwner[arrindx].clear();
17996
17997 if(localRAM[arrindx].Valid())
17998 localRAM[arrindx].Clear();
17999
18000 arrayOwner[arrindx].specCleared = true;
18001 }
18002 else if(arrindx < 0) //object array
18003 Z_scripterrlog_force_trace("Cannot 'DestroyArray()' an object-based array '%d'\n", arrindx);
18004 }
18005 else Z_scripterrlog_force_trace("Tried to 'DestroyArray()' an invalid array '%d'\n", arrindx);
18006 }
18007
18008 13698919 static dword allocatemem_old(int32_t size, bool local, ScriptType type, const uint32_t UID, script_object_type object_type)
18009 {
18010 dword ptrval;
18011
18012
1/2
✓ Branch 0 taken 13698919 times.
✗ Branch 1 not taken.
13698919 if(size < 0)
18013 {
18014 Z_scripterrlog_force_trace("Array initialized to invalid size of %d\n", size);
18015 return 0;
18016 }
18017
18018
2/2
✓ Branch 0 taken 13698125 times.
✓ Branch 1 taken 794 times.
13698919 if(local)
18019 {
18020 //localRAM[0] is used as an invalid container, so 0 can be the NULL pointer in ZScript
18021
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 446326904 times.
✓ Branch 2 taken 432628779 times.
✓ Branch 3 taken 13698125 times.
446326904 for(ptrval = 1; ptrval < NUM_ZSCRIPT_ARRAYS && localRAM[ptrval].Valid(); ptrval++) ;
18022
18023
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13698125 times.
13698125 if(ptrval >= NUM_ZSCRIPT_ARRAYS)
18024 {
18025 Z_scripterrlog_force_trace("%d local arrays already in use, no more can be allocated\n", NUM_ZSCRIPT_ARRAYS-1);
18026 ptrval = 0;
18027 DCHECK(false);
18028 }
18029 else
18030 {
18031 13698125 ZScriptArray &a = localRAM[ptrval];
18032
18033 13698125 a.Resize(size);
18034 13698125 a.setValid(true);
18035 13698125 a.setObjectType(object_type);
18036
18037
2/2
✓ Branch 0 taken 211604475 times.
✓ Branch 1 taken 13698125 times.
225302600 for(dword j = 0; j < (dword)size; j++)
18038 211604475 a[j] = 0; //initialize array
18039
18040 // Keep track of which object created the array so we know which to deallocate
18041 13698125 arrayOwner[ptrval].clear();
18042 13698125 arrayOwner[ptrval].reown(type, UID);
18043 }
18044 13698125 }
18045 else
18046 {
18047 //Globals are only allocated here at first play, otherwise in init_game
18048
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 24013 times.
✓ Branch 2 taken 23219 times.
✓ Branch 3 taken 794 times.
24013 for(ptrval = 0; ptrval < game->globalRAM.size() && game->globalRAM[ptrval].Valid(); ptrval++) ;
18049
18050
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 794 times.
794 if(ptrval >= game->globalRAM.size())
18051 {
18052 Z_scripterrlog_force_trace("Invalid pointer value of %u passed to global allocate\n", ptrval);
18053 ptrval = 0;
18054 //this shouldn't happen, unless people are putting ALLOCATEGMEM in their ZASM scripts where they shouldn't be
18055 DCHECK(false);
18056 return ptrval * 10000;
18057 }
18058
18059 794 ZScriptArray &a = game->globalRAM[ptrval];
18060
18061 794 a.Resize(size);
18062 794 a.setValid(true);
18063 794 a.setObjectType(object_type);
18064
18065
2/2
✓ Branch 0 taken 1124622 times.
✓ Branch 1 taken 794 times.
1125416 for(dword j = 0; j < (dword)size; j++)
18066 1124622 a[j] = 0;
18067
18068 794 ptrval += NUM_ZSCRIPT_ARRAYS; //so each pointer has a unique value
18069 }
18070
18071 13698919 return ptrval * 10000;
18072 13698919 }
18073
18074 14192030 uint32_t allocatemem(int32_t size, bool local, ScriptType type, const uint32_t UID, script_object_type object_type)
18075 {
18076
2/2
✓ Branch 0 taken 13698919 times.
✓ Branch 1 taken 493111 times.
14192030 if (!ZScriptVersion::gc_arrays())
18077 13698919 return allocatemem_old(size, local, type, UID, object_type);
18078
18079
1/2
✓ Branch 0 taken 493111 times.
✗ Branch 1 not taken.
493111 if(size < 0)
18080 {
18081 Z_scripterrlog_force_trace("Array initialized to invalid size of %d\n", size);
18082 return 0;
18083 }
18084
18085 493111 auto* array = script_arrays.create();
18086
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 493111 times.
493111 if (!array)
18087 return 0;
18088
18089 493111 ZScriptArray &a = array->arr;
18090 493111 a.Resize(size);
18091 493111 a.setValid(true);
18092 493111 a.setObjectType(object_type);
18093
18094
2/2
✓ Branch 0 taken 28732918 times.
✓ Branch 1 taken 493111 times.
29226029 for(dword j = 0; j < (dword)size; j++)
18095 28732918 a[j] = 0; //initialize array
18096
18097 493111 return array->id;
18098 14192030 }
18099
18100 14192030 void do_allocatemem(bool v, const bool local, ScriptType type, const uint32_t UID)
18101 {
18102 14192030 int32_t size = SH::get_arg(sarg2, v) / 10000;
18103
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 14192030 times.
✓ Branch 2 taken 14192030 times.
✗ Branch 3 not taken.
14192030 assert(sarg3 >= 0 && sarg3 <= (int)script_object_type::last);
18104 14192030 uint32_t id = allocatemem(size, local, type, UID, (script_object_type)sarg3);
18105 14192030 set_register(sarg1, id);
18106 14192030 }
18107
18108 13664241 void do_deallocatemem()
18109 {
18110 13664241 const int32_t ptrval = get_register(sarg1) / 10000;
18111
18112 13664241 FFScript::deallocateArray(ptrval);
18113 13664241 }
18114
18115 ///----------------------------------------------------------------------------------------------------//
18116 //Mathematical
18117
18118 4789964 void do_add(const bool v)
18119 {
18120 4789964 int32_t temp = SH::get_arg(sarg2, v);
18121 4789964 int32_t temp2 = get_register(sarg1);
18122
18123 4789964 set_register(sarg1, temp2 + temp);
18124 4789964 }
18125
18126 208774 void do_sub(bool v, const bool inv = false)
18127 {
18128 208774 bool v2 = false;
18129
2/2
✓ Branch 0 taken 208768 times.
✓ Branch 1 taken 6 times.
208774 if(inv) zc_swap(v,v2);
18130
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 208768 times.
208774 auto destreg = (inv ? sarg2 : sarg1);
18131 208774 int32_t temp = SH::get_arg(sarg2, v);
18132 208774 int32_t temp2 = SH::get_arg(sarg1, v2);
18133 208774 set_register(destreg, temp2 - temp);
18134 208774 }
18135
18136 269318 void do_mult(const bool v)
18137 {
18138 269318 int64_t temp = SH::get_arg(sarg2, v);
18139 269318 int32_t temp2 = get_register(sarg1);
18140
18141 269318 set_register(sarg1, int32_t((temp * temp2) / 10000));
18142 269318 }
18143
18144 23952 void do_div(bool v, const bool inv = false)
18145 {
18146 23952 bool v2 = false;
18147
1/2
✓ Branch 0 taken 23952 times.
✗ Branch 1 not taken.
23952 if(inv) zc_swap(v,v2);
18148
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23952 times.
23952 auto destreg = (inv ? sarg2 : sarg1);
18149 23952 int64_t temp = SH::get_arg(sarg2, v);
18150 23952 int64_t temp2 = SH::get_arg(sarg1, v2);
18151
18152
1/2
✓ Branch 0 taken 23952 times.
✗ Branch 1 not taken.
23952 if(temp == 0)
18153 {
18154 scripting_log_error_with_context("Attempted to divide by zero!");
18155 set_register(destreg, int32_t(sign(temp2) * MAX_SIGNED_32));
18156 }
18157 else
18158 {
18159 23952 set_register(destreg, int32_t((temp2 * 10000) / temp));
18160 }
18161 23952 }
18162
18163 41814 void do_mod(bool v, const bool inv = false)
18164 {
18165 41814 bool v2 = false;
18166
1/2
✓ Branch 0 taken 41814 times.
✗ Branch 1 not taken.
41814 if(inv) zc_swap(v,v2);
18167
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41814 times.
41814 auto destreg = (inv ? sarg2 : sarg1);
18168 41814 int32_t temp = SH::get_arg(sarg2, v);
18169 41814 int32_t temp2 = SH::get_arg(sarg1, v2);
18170
18171
1/2
✓ Branch 0 taken 41814 times.
✗ Branch 1 not taken.
41814 if(temp == 0)
18172 {
18173 scripting_log_error_with_context("Attempted to modulo by zero!");
18174 temp = 1;
18175 }
18176
18177 41814 set_register(destreg, temp2 % temp);
18178 41814 }
18179
18180 16449574 void do_trig(const bool v, const byte type)
18181 {
18182 16449574 double rangle = (SH::get_arg(sarg2, v) / 10000.0) * PI / 180.0;
18183
18184
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 9768934 times.
✓ Branch 2 taken 6680540 times.
✓ Branch 3 taken 100 times.
16449574 switch(type)
18185 {
18186 case 0:
18187 9768934 set_register(sarg1, int32_t(zc::math::Sin(rangle) * 10000.0));
18188 9768934 break;
18189
18190 case 1:
18191 6680540 set_register(sarg1, int32_t(zc::math::Cos(rangle) * 10000.0));
18192 6680540 break;
18193
18194 case 2:
18195 100 set_register(sarg1, int32_t(zc::math::Tan(rangle) * 10000.0));
18196 100 break;
18197 }
18198 16449574 }
18199
18200 3916 void do_degtorad()
18201 {
18202 3916 double rangle = (SH::get_arg(sarg2, false) / 10000.0) * (PI / 180.0);
18203 3916 rangle += rangle < 0?-0.00005:0.00005;
18204
18205 3916 set_register(sarg1, int32_t(rangle * 10000.0));
18206 3916 }
18207
18208 196075 void do_radtodeg()
18209 {
18210 196075 double rangle = (SH::get_arg(sarg2, false) / 10000.0) * (180.0 / PI);
18211
18212 196075 set_register(sarg1, int32_t(rangle * 10000.0));
18213 196075 }
18214
18215 14918 void do_asin(const bool v)
18216 {
18217 14918 double temp = double(SH::get_arg(sarg2, v)) / 10000.0;
18218
18219
2/4
✓ Branch 0 taken 14918 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14918 times.
✗ Branch 3 not taken.
14918 if(temp >= -1 && temp <= 1)
18220 14918 set_register(sarg1, int32_t(asin(temp) * 10000.0));
18221 else
18222 {
18223 Z_scripterrlog("Script attempted to pass %f into ArcSin!\n",temp);
18224 set_register(sarg1, -10000);
18225 }
18226 14918 }
18227
18228 void do_acos(const bool v)
18229 {
18230 double temp = double(SH::get_arg(sarg2, v)) / 10000.0;
18231
18232 if(temp >= -1 && temp <= 1)
18233 set_register(sarg1, int32_t(acos(temp) * 10000.0));
18234 else
18235 {
18236 Z_scripterrlog("Script attempted to pass %f into ArcCos!\n",temp);
18237 set_register(sarg1, -10000);
18238 }
18239 }
18240
18241 5902195 void do_arctan()
18242 {
18243 5902195 double xpos = GET_D(rINDEX) / 10000.0;
18244 5902195 double ypos = GET_D(rINDEX2) / 10000.0;
18245
18246 5902195 set_register(sarg1, int32_t(atan2(ypos, xpos) * 10000.0));
18247 5902195 }
18248
18249 8488 void do_abs(const bool v)
18250 {
18251 8488 int32_t temp = SH::get_arg(sarg1, v);
18252 8488 set_register(sarg1, abs(temp));
18253 8488 }
18254
18255 969 void do_log10(const bool v)
18256 {
18257 969 double temp = double(SH::get_arg(sarg1, v)) / 10000.0;
18258
18259
1/2
✓ Branch 0 taken 969 times.
✗ Branch 1 not taken.
969 if(temp > 0)
18260 969 set_register(sarg1, int32_t(log10(temp) * 10000.0));
18261 else
18262 {
18263 Z_scripterrlog("Script tried to calculate log of %f\n", temp / 10000.0);
18264 set_register(sarg1, 0);
18265 }
18266 969 }
18267
18268 648 void do_naturallog(const bool v)
18269 {
18270 648 double temp = double(SH::get_arg(sarg1, v)) / 10000.0;
18271
18272
1/2
✓ Branch 0 taken 648 times.
✗ Branch 1 not taken.
648 if(temp > 0)
18273 648 set_register(sarg1, int32_t(log(temp) * 10000.0));
18274 else
18275 {
18276 Z_scripterrlog("Script tried to calculate ln of %f\n", temp / 10000.0);
18277 set_register(sarg1, 0);
18278 }
18279 648 }
18280
18281 2121 void do_min(const bool v)
18282 {
18283 2121 int32_t temp = SH::get_arg(sarg2, v);
18284 2121 int32_t temp2 = get_register(sarg1);
18285
2/2
✓ Branch 0 taken 1067 times.
✓ Branch 1 taken 1054 times.
2121 set_register(sarg1, zc_min(temp2, temp));
18286 2121 }
18287
18288 1377 void do_max(const bool v)
18289 {
18290 1377 int32_t temp = SH::get_arg(sarg2, v);
18291 1377 int32_t temp2 = get_register(sarg1);
18292
18293
2/2
✓ Branch 0 taken 181 times.
✓ Branch 1 taken 1196 times.
1377 set_register(sarg1, zc_max(temp2, temp));
18294 1377 }
18295 8306 void do_wrap_rad(const bool v)
18296 {
18297 8306 SET_D(rEXP1, wrap_zslong_rad(SH::get_arg(sarg1, v)));
18298 8306 }
18299 13037 void do_wrap_deg(const bool v)
18300 {
18301 13037 SET_D(rEXP1, wrap_zslong_deg(SH::get_arg(sarg1, v)));
18302 13037 }
18303
18304
18305 2918055 void do_rnd(const bool v)
18306 {
18307 2918055 int32_t temp = SH::get_arg(sarg2, v) / 10000;
18308
18309
2/2
✓ Branch 0 taken 2892290 times.
✓ Branch 1 taken 25765 times.
2918055 if(temp > 0)
18310 2892290 set_register(sarg1, (zc_oldrand() % temp) * 10000);
18311
2/2
✓ Branch 0 taken 2755 times.
✓ Branch 1 taken 23010 times.
25765 else if(temp < 0)
18312 2755 set_register(sarg1, (zc_oldrand() % (-temp)) * -10000);
18313 else
18314 23010 set_register(sarg1, 0); // Just return 0. (Do not log an error)
18315 2918055 }
18316
18317 void do_srnd(const bool v)
18318 {
18319 uint32_t seed = SH::get_arg(sarg1, v); //Do not `/10000`- allow the decimal portion to be used! -V
18320 zc_game_srand(seed);
18321 }
18322
18323 void do_srndrnd()
18324 {
18325 //Randomize the seed to the current system time, + or - the product of 2 random numbers.
18326 int32_t seed = time(0) + ((zc_rand() * int64_t(zc_rand())) * (zc_rand(1) ? 1 : -1));
18327 set_register(sarg1, seed);
18328 zc_game_srand(seed);
18329 }
18330
18331 //Returns the system Real-Time-Clock value.
18332 15 void FFScript::getRTC()
18333 {
18334 //int32_t type = get_register(sarg1) / 10000;
18335 //int32_t time = getTime(type);
18336 15 set_register(sarg1, getTime((get_register(sarg1) / 10000)) * 10000);
18337 15 }
18338
18339
18340 void do_factorial(const bool v)
18341 {
18342 int32_t temp;
18343
18344 if(v)
18345 return; //must factorial a register, not a value (why is this exactly? ~Joe123)
18346 else
18347 {
18348 temp = get_register(sarg1) / 10000;
18349
18350 if(temp < 2)
18351 {
18352 set_register(sarg1, temp >= 0 ? 10000 : 0);
18353 return;
18354 }
18355 }
18356
18357 int32_t temp2 = 1;
18358
18359 for(int32_t temp3 = temp; temp > 1; temp--)
18360 temp2 *= temp3;
18361
18362 set_register(sarg1, temp2 * 10000);
18363 }
18364
18365 6556 void do_power(bool v, const bool inv = false)
18366 {
18367 6556 bool v2 = false;
18368
1/2
✓ Branch 0 taken 6556 times.
✗ Branch 1 not taken.
6556 if(inv) zc_swap(v,v2);
18369
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6556 times.
6556 auto destreg = (inv ? sarg2 : sarg1);
18370 6556 double temp = double(SH::get_arg(sarg2, v)) / 10000.0;
18371 6556 double temp2 = double(SH::get_arg(sarg1, v2)) / 10000.0;
18372
18373
3/4
✓ Branch 0 taken 1293 times.
✓ Branch 1 taken 5263 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1293 times.
6556 if(temp == 0 && temp2 == 0)
18374 {
18375 set_register(destreg, 10000);
18376 return;
18377 }
18378
18379 6556 set_register(destreg, int32_t(pow(temp2, temp) * 10000.0));
18380 6556 }
18381
18382 void do_lpower(bool v, const bool inv = false)
18383 {
18384 bool v2 = false;
18385 if(inv) zc_swap(v,v2);
18386 auto destreg = (inv ? sarg2 : sarg1);
18387 int32_t temp = SH::get_arg(sarg2, v);
18388 int32_t temp2 = SH::get_arg(sarg1, v2);
18389
18390 if(temp == 0 && temp2 == 0)
18391 {
18392 set_register(destreg, 1);
18393 return;
18394 }
18395
18396 set_register(destreg, int32_t(pow(temp2, temp)));
18397 }
18398
18399 //could use recursion or something to avoid truncation.
18400 void do_ipower(const bool v)
18401 {
18402 double sarg2val = double(SH::get_arg(sarg2, v));
18403 if ( sarg2val == 0 )
18404 {
18405 Z_scripterrlog("Division by 0 Err: InvPower() exponent divisor cannot be 0!!\n");
18406 set_register(sarg1, 1);
18407 return;
18408 }
18409 double temp = 10000.0 / sarg2val;
18410 double temp2 = double(get_register(sarg1)) / 10000.0;
18411
18412 if(temp == 0 && temp2 == 0)
18413 {
18414 set_register(sarg1, 1);
18415 return;
18416 }
18417
18418 set_register(sarg1, int32_t(pow(temp2, temp) * 10000.0));
18419 }
18420
18421 10089782 void do_sqroot(const bool v)
18422 {
18423 10089782 double temp = double(SH::get_arg(sarg2, v)) / 10000.0;
18424
18425
2/2
✓ Branch 0 taken 422 times.
✓ Branch 1 taken 10089360 times.
10089782 if(temp < 0)
18426 {
18427 422 Z_scripterrlog("Script attempted to calculate square root of %f!\n", temp);
18428 422 set_register(sarg1, -10000);
18429 422 return;
18430 }
18431
18432 10089360 set_register(sarg1, int32_t(sqrt(temp) * 10000.0));
18433 10089782 }
18434
18435 ///----------------------------------------------------------------------------------------------------//
18436 //Bitwise
18437
18438 155310 void do_and(const bool v)
18439 {
18440 155310 int32_t temp = SH::get_arg(sarg2, v) / 10000;
18441 155310 int32_t temp2 = get_register(sarg1) / 10000;
18442 155310 set_register(sarg1, (temp2 & temp) * 10000);
18443 155310 }
18444
18445 362787 void do_and32(const bool v)
18446 {
18447 362787 int32_t temp = SH::get_arg(sarg2, v);
18448 362787 int32_t temp2 = get_register(sarg1);
18449 362787 set_register(sarg1, (temp2 & temp));
18450 362787 }
18451
18452 3867 void do_or(const bool v)
18453 {
18454 3867 int32_t temp = SH::get_arg(sarg2, v) / 10000;
18455 3867 int32_t temp2 = get_register(sarg1) / 10000;
18456 3867 set_register(sarg1, (temp2 | temp) * 10000);
18457 3867 }
18458
18459 void do_or32(const bool v)
18460 {
18461 int32_t temp = SH::get_arg(sarg2, v);
18462 int32_t temp2 = get_register(sarg1);
18463 set_register(sarg1, (temp2 | temp));
18464 }
18465
18466 927917 void do_xor(const bool v)
18467 {
18468 927917 int32_t temp = SH::get_arg(sarg2, v) / 10000;
18469 927917 int32_t temp2 = get_register(sarg1) / 10000;
18470 927917 set_register(sarg1, (temp2 ^ temp) * 10000);
18471 927917 }
18472
18473 void do_xor32(const bool v)
18474 {
18475 int32_t temp = SH::get_arg(sarg2, v);
18476 int32_t temp2 = get_register(sarg1);
18477 set_register(sarg1, (temp2 ^ temp));
18478 }
18479
18480 void do_nand(const bool v)
18481 {
18482 int32_t temp = SH::get_arg(sarg2, v) / 10000;
18483 int32_t temp2 = get_register(sarg1) / 10000;
18484 set_register(sarg1, (~(temp2 & temp)) * 10000);
18485 }
18486
18487 void do_nor(const bool v)
18488 {
18489 int32_t temp = SH::get_arg(sarg2, v) / 10000;
18490 int32_t temp2 = get_register(sarg1) / 10000;
18491 set_register(sarg1, (~(temp2 | temp)) * 10000);
18492 }
18493
18494 void do_xnor(const bool v)
18495 {
18496 int32_t temp = SH::get_arg(sarg2, v) / 10000;
18497 int32_t temp2 = get_register(sarg1) / 10000;
18498 set_register(sarg1, (~(temp2 ^ temp)) * 10000);
18499 }
18500
18501 void do_not(const bool v)
18502 {
18503 int32_t temp = SH::get_arg(sarg2, v);
18504 set_register(sarg1, !temp);
18505 }
18506
18507 3719887 void do_bitwisenot(const bool v)
18508 {
18509 3719887 int32_t temp = SH::get_arg(sarg1, v) / 10000;
18510 3719887 set_register(sarg1, (~temp) * 10000);
18511 3719887 }
18512
18513 4 void do_bitwisenot32(const bool v)
18514 {
18515 4 int32_t temp = SH::get_arg(sarg1, v);
18516 4 set_register(sarg1, (~temp));
18517 4 }
18518
18519 85034159 void do_lshift(const bool v)
18520 {
18521 85034159 int32_t temp = SH::get_arg(sarg2, v) / 10000;
18522 85034159 int32_t temp2 = get_register(sarg1) / 10000;
18523 85034159 set_register(sarg1, (temp2 << temp) * 10000);
18524 85034159 }
18525
18526 317888 void do_lshift32(const bool v)
18527 {
18528 317888 int32_t temp = SH::get_arg(sarg2, v) / 10000;
18529 317888 int32_t temp2 = get_register(sarg1);
18530 317888 set_register(sarg1, (temp2 << temp));
18531 317888 }
18532
18533 31991089 void do_rshift(const bool v)
18534 {
18535 31991089 int32_t temp = SH::get_arg(sarg2, v) / 10000;
18536 31991089 int32_t temp2 = get_register(sarg1) / 10000;
18537 31991089 set_register(sarg1, (temp2 >> temp) * 10000);
18538 31991089 }
18539
18540 34296 void do_rshift32(const bool v)
18541 {
18542 34296 int32_t temp = SH::get_arg(sarg2, v) / 10000;
18543 34296 int32_t temp2 = get_register(sarg1);
18544 34296 set_register(sarg1, (temp2 >> temp));
18545 34296 }
18546
18547 ///----------------------------------------------------------------------------------------------------//
18548 //Casting
18549
18550 void do_boolcast(const bool isFloat)
18551 {
18552 set_register(sarg1, (get_register(sarg1) ? (isFloat ? 1 : 10000) : 0));
18553 }
18554
18555 ///----------------------------------------------------------------------------------------------------//
18556 //Text ptr functions
18557 32282 void do_fontheight()
18558 {
18559 32282 int32_t font = get_register(sarg1)/10000;
18560 32282 SET_D(rEXP1, text_height(get_zc_font(font))*10000);
18561 32282 }
18562
18563 18404 void do_strwidth()
18564 {
18565 18404 int32_t strptr = get_register(sarg1);
18566 18404 int32_t font = get_register(sarg2)/10000;
18567 18404 string the_string;
18568
1/2
✓ Branch 0 taken 18404 times.
✗ Branch 1 not taken.
18404 ArrayH::getString(strptr, the_string, 512);
18569
2/4
✓ Branch 0 taken 18404 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18404 times.
✗ Branch 3 not taken.
18404 SET_D(rEXP1, text_length(get_zc_font(font), the_string.c_str())*10000);
18570 18404 }
18571
18572 250385 void do_charwidth()
18573 {
18574 250385 char chr = get_register(sarg1)/10000;
18575 250385 int32_t font = get_register(sarg2)/10000;
18576 250385 char *cstr = new char[2];
18577 250385 cstr[0] = chr;
18578 250385 cstr[1] = '\0';
18579 250385 SET_D(rEXP1, text_length(get_zc_font(font), cstr)*10000);
18580
1/2
✓ Branch 0 taken 250385 times.
✗ Branch 1 not taken.
250385 delete[] cstr;
18581 250385 }
18582
18583 int32_t do_msgwidth(int32_t ID)
18584 {
18585 if(BC::checkMessage(ID) != SH::_NoError)
18586 {
18587 return -1;
18588 }
18589
18590 int32_t v = text_length(get_zc_font(MsgStrings[ID].font),
18591 MsgStrings[ID].s.substr(0,MsgStrings[ID].s.find_last_not_of(' ')+1).c_str());
18592 return v;
18593 }
18594
18595 int32_t do_msgheight(int32_t ID)
18596 {
18597 if(BC::checkMessage(ID) != SH::_NoError)
18598 {
18599 return -1;
18600 }
18601 return text_height(get_zc_font(MsgStrings[ID].font));
18602 }
18603
18604 ///----------------------------------------------------------------------------------------------------//
18605 //Gameplay functions
18606
18607 123 void do_warp(bool v)
18608 {
18609 123 int32_t dmapid = SH::get_arg(sarg1, v) / 10000;
18610 123 int32_t screen = SH::get_arg(sarg2, v) / 10000;
18611
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 123 times.
123 if ( ((unsigned)dmapid) >= MAXDMAPS )
18612 {
18613 Z_scripterrlog("Invalid DMap ID (%d) passed to Warp(). Aborting.\n", dmapid);
18614 return;
18615 }
18616
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 123 times.
123 if ( ((unsigned)screen) >= MAPSCRS )
18617 {
18618 Z_scripterrlog("Invalid Screen Index (%d) passed to Warp(). Aborting.\n", screen);
18619 return;
18620 }
18621
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 123 times.
123 if ( map_screen_index(DMaps[dmapid].map, screen + DMaps[dmapid].xoff) >= (int32_t)TheMaps.size() )
18622 {
18623 Z_scripterrlog("Invalid destination passed to Warp(). Aborting.\n");
18624 return;
18625 }
18626 123 hero_scr->sidewarpdmap[0] = dmapid;
18627 123 hero_scr->sidewarpscr[0] = screen;
18628 123 hero_scr->sidewarptype[0] = wtIWARP;
18629
1/2
✓ Branch 0 taken 123 times.
✗ Branch 1 not taken.
123 if(!get_qr(qr_OLD_HERO_WARP_RETSQUARE))
18630 {
18631 hero_scr->warpreturnc &= ~(3 << 8);
18632 set_bit(&hero_scr->sidewarpoverlayflags,0,0);
18633 }
18634 123 Hero.ffwarp = true;
18635 123 }
18636
18637 127 void do_pitwarp(bool v)
18638 {
18639 127 int32_t dmapid = SH::get_arg(sarg1, v) / 10000;
18640 127 int32_t screen = SH::get_arg(sarg2, v) / 10000;
18641
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 127 times.
127 if ( ((unsigned)dmapid) >= MAXDMAPS )
18642 {
18643 Z_scripterrlog("Invalid DMap ID (%d) passed to PitWarp(). Aborting.\n", dmapid);
18644 return;
18645 }
18646
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 127 times.
127 if ( ((unsigned)screen) >= MAPSCRS )
18647 {
18648 Z_scripterrlog("Invalid Screen Index (%d) passed to PitWarp(). Aborting.\n", screen);
18649 return;
18650 }
18651 //Extra sanity guard.
18652
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 127 times.
127 if ( map_screen_index(DMaps[dmapid].map, screen + DMaps[dmapid].xoff) >= (int32_t)TheMaps.size() )
18653 {
18654 Z_scripterrlog("Invalid destination passed to Warp(). Aborting.\n");
18655 return;
18656 }
18657 127 hero_scr->sidewarpdmap[0] = dmapid;
18658 127 hero_scr->sidewarpscr[0] = screen;
18659 127 hero_scr->sidewarptype[0] = wtIWARP;
18660
1/2
✓ Branch 0 taken 127 times.
✗ Branch 1 not taken.
127 if(!get_qr(qr_OLD_HERO_WARP_RETSQUARE))
18661 {
18662 hero_scr->warpreturnc &= ~(3 << 8);
18663 set_bit(&hero_scr->sidewarpoverlayflags,0,0);
18664 }
18665 127 Hero.ffwarp = true;
18666 127 Hero.ffpit = true;
18667 127 }
18668
18669
18670
18671 void do_showsavescreen()
18672 {
18673 bool didsaved = save_game(false, 0);
18674 set_register(sarg1, didsaved ? 10000 : 0);
18675 }
18676
18677 11096 void do_selectweapon(bool v, int32_t btn)
18678 {
18679
2/4
✓ Branch 0 taken 5436 times.
✓ Branch 1 taken 5660 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
11096 switch(btn)
18680 {
18681 case 1:
18682
1/2
✓ Branch 0 taken 5660 times.
✗ Branch 1 not taken.
5660 if(!get_qr(qr_SELECTAWPN))
18683 return;
18684 5660 break;
18685 case 2:
18686 if(!get_qr(qr_SET_XBUTTON_ITEMS))
18687 return;
18688 break;
18689 case 3:
18690 if(!get_qr(qr_SET_YBUTTON_ITEMS))
18691 return;
18692 break;
18693 }
18694
18695 11096 byte dir=(byte)(SH::get_arg(sarg1, v)/10000);
18696
18697 // Selection directions don't match the normal ones...
18698
2/5
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 80 times.
✓ Branch 4 taken 11016 times.
11096 switch(dir)
18699 {
18700 case 0:
18701 dir=SEL_UP;
18702 break;
18703
18704 case 1:
18705 dir=SEL_DOWN;
18706 break;
18707
18708 case 2:
18709 80 dir=SEL_LEFT;
18710 80 break;
18711
18712 case 3:
18713 11016 dir=SEL_RIGHT;
18714 11016 break;
18715
18716 default:
18717 return;
18718 }
18719
18720
2/5
✗ Branch 0 not taken.
✓ Branch 1 taken 5436 times.
✓ Branch 2 taken 5660 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
11096 switch(btn)
18721 {
18722 case 0:
18723 5436 selectNextBWpn(dir);
18724 5436 break;
18725 case 1:
18726 5660 selectNextAWpn(dir);
18727 5660 break;
18728 case 2:
18729 selectNextXWpn(dir);
18730 break;
18731 case 3:
18732 selectNextYWpn(dir);
18733 break;
18734 }
18735 11096 }
18736
18737 ///----------------------------------------------------------------------------------------------------//
18738 //Screen Information
18739
18740 25461489 void do_issolid()
18741 {
18742 25461489 int32_t x = int32_t(GET_D(rINDEX) / 10000);
18743 25461489 int32_t y = int32_t(GET_D(rINDEX2) / 10000);
18744
18745 25461489 set_register(sarg1, (_walkflag(x, y, 1) ? 10000 : 0));
18746 25461489 }
18747
18748 void do_mapdataissolid()
18749 {
18750 int32_t x = int32_t(GET_D(rINDEX) / 10000);
18751 int32_t y = int32_t(GET_D(rINDEX2) / 10000);
18752
18753 auto result = decode_mapdata_ref(GET_REF(mapdataref));
18754 if (!result.scr)
18755 {
18756 scripting_log_error_with_context("mapdata pointer is either invalid or uninitialised");
18757 set_register(sarg1,10000);
18758 }
18759 else
18760 {
18761 if (result.type == mapdata_type::CanonicalScreen)
18762 {
18763 set_register(sarg1, (_walkflag(x, y, 1, result.scr) ? 10000 : 0));
18764 return;
18765 }
18766
18767 if (result.type == mapdata_type::TemporaryCurrentRegion && result.layer == 0)
18768 {
18769 set_register(sarg1, (_walkflag(x, y, 1)) ? 10000 : 0);
18770 }
18771 else if (result.type == mapdata_type::TemporaryScrollingRegion && result.layer == 0)
18772 {
18773 mapscr* s0 = GetScrollingMapscr(0, x, y);
18774 mapscr* s1 = GetScrollingMapscr(1, x, y);
18775 mapscr* s2 = GetScrollingMapscr(2, x, y);
18776 if (!s1->valid) s1 = s0;
18777 if (!s2->valid) s2 = s0;
18778 bool result = _walkflag_new(s0, s1, s2, x, y, 0_zf, true);
18779 set_register(sarg1, result ? 10000 : 0);
18780 }
18781 else
18782 {
18783 set_register(sarg1, (_walkflag(x, y, 1, result.scr) ? 10000 : 0));
18784 }
18785 }
18786 }
18787
18788 void do_mapdataissolid_layer()
18789 {
18790 int32_t x = int32_t(GET_D(rINDEX) / 10000);
18791 int32_t y = int32_t(GET_D(rINDEX2) / 10000);
18792 int32_t layer = int32_t(GET_D(rEXP1) / 10000);
18793
18794 auto result = decode_mapdata_ref(GET_REF(mapdataref));
18795 if (!result.scr)
18796 {
18797 scripting_log_error_with_context("mapdata pointer is either invalid or uninitialised");
18798 set_register(sarg1,10000);
18799 }
18800 else
18801 {
18802 if(BC::checkBounds(layer, 0, 6) != SH::_NoError)
18803 {
18804 set_register(sarg1,10000);
18805 }
18806 else
18807 {
18808 if (result.type == mapdata_type::TemporaryCurrentRegion && result.layer == 0)
18809 {
18810 set_register(sarg1, (_walkflag_layer(x, y, 1, result.scr)) ? 10000 : 0);
18811 }
18812 else if (result.type == mapdata_type::TemporaryScrollingRegion && result.layer == 0)
18813 {
18814 set_register(sarg1, (_walkflag_layer_scrolling(x, y, 1, result.scr)) ? 10000 : 0);
18815 }
18816 else
18817 {
18818 mapscr* m = result.scr;
18819
18820 if(layer > 0)
18821 {
18822 if(m->layermap[layer] == 0)
18823 {
18824 set_register(sarg1,10000);
18825 return;
18826 }
18827
18828 m = &TheMaps[(m->layermap[layer]*MAPSCRS + m->layerscreen[layer])];
18829 }
18830
18831 set_register(sarg1, (_walkflag_layer(x, y, 1, m) ? 10000 : 0));
18832 }
18833 }
18834 }
18835 }
18836
18837 void do_issolid_layer()
18838 {
18839 int32_t x = int32_t(GET_D(rINDEX) / 10000);
18840 int32_t y = int32_t(GET_D(rINDEX2) / 10000);
18841 int32_t layer = int32_t(GET_D(rEXP1) / 10000);
18842
18843 if(BC::checkBounds(layer, 0, 6) != SH::_NoError)
18844 {
18845 set_register(sarg1,10000);
18846 }
18847 else
18848 {
18849 set_register(sarg1, (_walkflag_layer(x, y, layer - 1, 1)) ? 10000 : 0);
18850 }
18851 }
18852
18853 257 void do_setsidewarp()
18854 {
18855 257 int32_t warp = SH::read_stack(ri->sp + 3) / 10000;
18856 257 int32_t scrn = SH::read_stack(ri->sp + 2) / 10000;
18857 257 int32_t dmap = SH::read_stack(ri->sp + 1) / 10000;
18858 257 int32_t type = SH::read_stack(ri->sp + 0) / 10000;
18859
18860 257 current_zasm_extra_context = "warp";
18861
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 257 times.
257 if (BC::checkBounds(warp, -1, 3) != SH::_NoError)
18862 return;
18863
18864 257 current_zasm_extra_context = "screen";
18865
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 257 times.
257 if (BC::checkBounds(scrn, -1, 0x87) != SH::_NoError)
18866 return;
18867
18868 257 current_zasm_extra_context = "dmap";
18869
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 257 times.
257 if (BC::checkBounds(dmap, -1, MAXDMAPS - 1) != SH::_NoError)
18870 return;
18871
18872 257 current_zasm_extra_context = "type";
18873
1/2
✓ Branch 0 taken 257 times.
✗ Branch 1 not taken.
257 if (BC::checkBounds(type, -1, wtMAX - 1) != SH::_NoError)
18874 return;
18875
18876 257 current_zasm_extra_context = "";
18877
18878 257 mapscr* scr = get_scr(GET_REF(screenref));
18879
18880
1/2
✓ Branch 0 taken 257 times.
✗ Branch 1 not taken.
257 if(scrn > -1)
18881 257 scr->sidewarpscr[warp] = scrn;
18882
18883
1/2
✓ Branch 0 taken 257 times.
✗ Branch 1 not taken.
257 if(dmap > -1)
18884 257 scr->sidewarpdmap[warp] = dmap;
18885
18886
1/2
✓ Branch 0 taken 257 times.
✗ Branch 1 not taken.
257 if(type > -1)
18887 257 scr->sidewarptype[warp] = type;
18888 257 }
18889
18890 5 void do_settilewarp()
18891 {
18892 5 int32_t warp = SH::read_stack(ri->sp + 3) / 10000;
18893 5 int32_t scrn = SH::read_stack(ri->sp + 2) / 10000;
18894 5 int32_t dmap = SH::read_stack(ri->sp + 1) / 10000;
18895 5 int32_t type = SH::read_stack(ri->sp + 0) / 10000;
18896
18897 5 current_zasm_extra_context = "warp";
18898
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (BC::checkBounds(warp, -1, 3) != SH::_NoError)
18899 return;
18900
18901 5 current_zasm_extra_context = "screen";
18902
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (BC::checkBounds(scrn, -1, 0x87) != SH::_NoError)
18903 return;
18904
18905 5 current_zasm_extra_context = "dmap";
18906
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (BC::checkBounds(dmap, -1, MAXDMAPS - 1) != SH::_NoError)
18907 return;
18908
18909 5 current_zasm_extra_context = "type";
18910
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (BC::checkBounds(type, -1, wtMAX - 1) != SH::_NoError)
18911 return;
18912
18913 5 current_zasm_extra_context = "";
18914
18915 5 mapscr* scr = get_scr(GET_REF(screenref));
18916
18917
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if(scrn > -1)
18918 5 scr->tilewarpscr[warp] = scrn;
18919
18920
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if(dmap > -1)
18921 5 scr->tilewarpdmap[warp] = dmap;
18922
18923
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if(type > -1)
18924 5 scr->tilewarptype[warp] = type;
18925 5 }
18926
18927 364895 void do_getsidewarpdmap(const bool v)
18928 {
18929 364895 int32_t warp = SH::get_arg(sarg1, v) / 10000;
18930
18931
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 364895 times.
364895 if(BC::checkBounds(warp, -1, 3) != SH::_NoError)
18932 {
18933 set_register(sarg1, -10000);
18934 return;
18935 }
18936
18937 364895 set_register(sarg1, get_scr(GET_REF(screenref))->sidewarpdmap[warp]*10000);
18938 364895 }
18939
18940 3 void do_getsidewarpscr(const bool v)
18941 {
18942 3 int32_t warp = SH::get_arg(sarg1, v) / 10000;
18943
18944
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if(BC::checkBounds(warp, -1, 3) != SH::_NoError)
18945 {
18946 set_register(sarg1, -10000);
18947 return;
18948 }
18949
18950 3 set_register(sarg1, get_scr(GET_REF(screenref))->sidewarpscr[warp]*10000);
18951 3 }
18952
18953 void do_getsidewarptype(const bool v)
18954 {
18955 int32_t warp = SH::get_arg(sarg1, v) / 10000;
18956
18957 if(BC::checkBounds(warp, -1, 3) != SH::_NoError)
18958 {
18959 set_register(sarg1, -10000);
18960 return;
18961 }
18962
18963 set_register(sarg1, get_scr(GET_REF(screenref))->sidewarptype[warp]*10000);
18964 }
18965
18966 364942 void do_gettilewarpdmap(const bool v)
18967 {
18968 364942 int32_t warp = SH::get_arg(sarg1, v) / 10000;
18969
18970
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 364942 times.
364942 if(BC::checkBounds(warp, -1, 3) != SH::_NoError)
18971 {
18972 set_register(sarg1, -10000);
18973 return;
18974 }
18975
18976 364942 set_register(sarg1, get_scr(GET_REF(screenref))->tilewarpdmap[warp]*10000);
18977 364942 }
18978
18979 50 void do_gettilewarpscr(const bool v)
18980 {
18981 50 int32_t warp = SH::get_arg(sarg1, v) / 10000;
18982
18983
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
50 if(BC::checkBounds(warp, -1, 3) != SH::_NoError)
18984 {
18985 set_register(sarg1, -10000);
18986 return;
18987 }
18988
18989 50 set_register(sarg1, get_scr(GET_REF(screenref))->tilewarpscr[warp]*10000);
18990 50 }
18991
18992 3 void do_gettilewarptype(const bool v)
18993 {
18994 3 int32_t warp = SH::get_arg(sarg1, v) / 10000;
18995
18996
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if(BC::checkBounds(warp, -1, 3) != SH::_NoError)
18997 {
18998 set_register(sarg1, -10000);
18999 return;
19000 }
19001
19002 3 set_register(sarg1, get_scr(GET_REF(screenref))->tilewarptype[warp]*10000);
19003 3 }
19004
19005 13670631 void do_layerscreen()
19006 {
19007 13670631 int32_t layer = (get_register(sarg2) / 10000) - 1;
19008
19009
3/4
✓ Branch 0 taken 13670631 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11796293 times.
✓ Branch 3 taken 1874338 times.
13670631 if(BC::checkBounds(layer, 0, 5) != SH::_NoError || get_scr(GET_REF(screenref))->layermap[layer] == 0)
19010 1874338 set_register(sarg1, -10000);
19011 else
19012 11796293 set_register(sarg1, get_scr(GET_REF(screenref))->layerscreen[layer] * 10000);
19013 13670631 }
19014
19015 18282859 void do_layermap()
19016 {
19017 18282859 int32_t layer = (get_register(sarg2) / 10000) - 1;
19018
19019
3/4
✓ Branch 0 taken 18282859 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15796322 times.
✓ Branch 3 taken 2486537 times.
18282859 if(BC::checkBounds(layer, 0, 5) != SH::_NoError || get_scr(GET_REF(screenref))->layermap[layer] == 0)
19020 2486537 set_register(sarg1, -10000);
19021 else
19022 15796322 set_register(sarg1, get_scr(GET_REF(screenref))->layermap[layer] * 10000);
19023 18282859 }
19024
19025
19026
19027 500 void do_triggersecrets(int screen)
19028 {
19029
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 500 times.
500 if (!is_in_current_region(screen))
19030 {
19031 scripting_log_error_with_context("Must be given a screen in the current region. got: {}", screen);
19032 return;
19033 }
19034
19035 500 trigger_secrets_for_screen(TriggerSource::Script, screen, false);
19036 500 }
19037
19038 void FFScript::do_graphics_getpixel()
19039 {
19040 int32_t ref = (GET_D(rEXP1));
19041 int32_t xpos = GET_D(rINDEX2) / 10000;
19042 int32_t ypos = (GET_D(rINDEX) / 10000);
19043
19044 BITMAP *bitty = FFCore.GetScriptBitmap(ref, screen);
19045
19046 const bool brokenOffset= ( (get_er(er_BITMAPOFFSET)!=0) || (get_qr(qr_BITMAPOFFSETFIX)!=0) );
19047 if(!brokenOffset && (ref-10) == -1 )
19048 {
19049 ypos += 56; //should this be -56?
19050 }
19051 else
19052 {
19053 ypos += 0;
19054 }
19055
19056 if(!bitty)
19057 {
19058 bitty = scrollbuf;
19059 }
19060
19061 // Note: getpixel will return -1 when out of bounds.
19062 if (!is_inside_bitmap(bitty, xpos, ypos, false))
19063 Z_scripterrlog("Invalid coordinate for getpixel. Bitmap: %dx%d, pixel: %dx%d\n", bitty->w, bitty->h, xpos, ypos);
19064
19065 int32_t ret = getpixel(bitty, xpos, ypos); //This is a palette index value.
19066
19067 if(!get_qr(qr_BROKEN_GETPIXEL_VALUE))
19068 ret *= 10000;
19069 set_register(sarg1, ret);
19070 }
19071
19072
19073
19074
19075 ///----------------------------------------------------------------------------------------------------//
19076 //Pointer handling
19077
19078 601509 bool is_valid_array(int32_t ptr)
19079 {
19080
2/2
✓ Branch 0 taken 601494 times.
✓ Branch 1 taken 15 times.
601509 if(!ptr) return false;
19081
19082
2/2
✓ Branch 0 taken 600928 times.
✓ Branch 1 taken 566 times.
601494 if (ZScriptVersion::gc_arrays())
19083 {
19084
1/2
✓ Branch 0 taken 600928 times.
✗ Branch 1 not taken.
600928 if (auto array = checkArray(ptr, true))
19085 600928 return !array->internal_expired;
19086
19087 return false;
19088 }
19089
19090 566 ptr /= 10000;
19091
19092
2/2
✓ Branch 0 taken 565 times.
✓ Branch 1 taken 1 times.
566 if(ptr < 0) //An object array?
19093 {
19094 1 int32_t objptr = -ptr;
19095 1 auto it = objectRAM.find(objptr);
19096
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(it == objectRAM.end())
19097 return false;
19098 1 return true;
19099 }
19100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 565 times.
565 else if(ptr >= NUM_ZSCRIPT_ARRAYS) //check global
19101 {
19102 dword gptr = ptr - NUM_ZSCRIPT_ARRAYS;
19103
19104 if(gptr > game->globalRAM.size())
19105 return false;
19106 else return game->globalRAM[gptr].Valid();
19107 }
19108 else
19109 {
19110 565 return localRAM[ptr].Valid();
19111 }
19112 601509 }
19113
19114 601509 void do_isvalidarray()
19115 {
19116 601509 int32_t ptr = get_register(sarg1);
19117
19118 601509 set_register(sarg1,is_valid_array(ptr) ? 10000 : 0);
19119 601509 }
19120
19121 31517 void do_isvaliditem()
19122 {
19123 31517 int32_t IID = get_register(sarg1);
19124 //int32_t ct = items.Count();
19125
19126 //for ( int32_t j = items.Count()-1; j >= 0; --j )
19127
2/2
✓ Branch 0 taken 55637 times.
✓ Branch 1 taken 213 times.
55850 for(int32_t j = 0; j < items.Count(); j++)
19128 //for(int32_t j = 0; j < ct; j++)
19129
2/2
✓ Branch 0 taken 31304 times.
✓ Branch 1 taken 24333 times.
55637 if(items.spr(j)->getUID() == IID)
19130 {
19131 31304 set_register(sarg1, 10000);
19132 31304 return;
19133 }
19134
19135 213 set_register(sarg1, 0);
19136 31517 }
19137
19138 11796078 void do_isvalidnpc()
19139 {
19140 11796078 int32_t UID = get_register(sarg1);
19141 //for ( int32_t j = guys.Count()-1; j >= 0; --j )
19142 //int32_t ct = guys.Count();
19143
19144
2/2
✓ Branch 0 taken 34259778 times.
✓ Branch 1 taken 112147 times.
34371925 for(int32_t j = 0; j < guys.Count(); j++)
19145 //for(int32_t j = 0; j < ct; j++)
19146
2/2
✓ Branch 0 taken 11683931 times.
✓ Branch 1 taken 22575847 times.
34259778 if(guys.spr(j)->getUID() == UID)
19147 {
19148 11683931 set_register(sarg1, 10000);
19149 11683931 return;
19150 }
19151
19152 112147 set_register(sarg1, 0);
19153 11796078 }
19154
19155 1279180 void do_isvalidlwpn()
19156 {
19157 1279180 int32_t WID = get_register(sarg1);
19158 //int32_t ct = Lwpns.Count();
19159
19160 //for ( int32_t j = Lwpns.Count()-1; j >= 0; --j )
19161
2/2
✓ Branch 0 taken 8771625 times.
✓ Branch 1 taken 590880 times.
9362505 for(int32_t j = 0; j < Lwpns.Count(); j++)
19162 //for(int32_t j = 0; j < ct; j++)
19163
2/2
✓ Branch 0 taken 8083325 times.
✓ Branch 1 taken 688300 times.
8771625 if(Lwpns.spr(j)->getUID() == WID)
19164 {
19165 688300 set_register(sarg1, 10000);
19166 688300 return;
19167 }
19168
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 590880 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
590880 if(Hero.lift_wpn && Hero.lift_wpn->getUID() == WID)
19169 {
19170 set_register(sarg1, 10000);
19171 return;
19172 }
19173 590880 set_register(sarg1, 0);
19174 1279180 }
19175
19176 176099 void do_isvalidewpn()
19177 {
19178 176099 int32_t WID = get_register(sarg1);
19179
19180
2/2
✓ Branch 0 taken 1360619 times.
✓ Branch 1 taken 24089 times.
1384708 for(int32_t j = 0; j < Ewpns.Count(); j++)
19181
2/2
✓ Branch 0 taken 1208609 times.
✓ Branch 1 taken 152010 times.
1360619 if(Ewpns.spr(j)->getUID() == WID)
19182 {
19183 152010 set_register(sarg1, 10000);
19184 152010 return;
19185 }
19186 // unsure how an ewpn would be lifted, but, checking just to be safe
19187
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 24089 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
24089 if(Hero.lift_wpn && Hero.lift_wpn->getUID() == WID)
19188 {
19189 set_register(sarg1, 10000);
19190 return;
19191 }
19192 24089 set_register(sarg1, 0);
19193 176099 }
19194
19195 void do_lwpnmakeangular()
19196 {
19197 if(LwpnH::loadWeapon(GET_REF(lwpnref)) == SH::_NoError)
19198 {
19199 auto w = LwpnH::getWeapon();
19200 if (!w->angular)
19201 {
19202 double vx;
19203 double vy;
19204 switch(NORMAL_DIR(w->dir))
19205 {
19206 case l_up:
19207 case l_down:
19208 case left:
19209 vx = -1.0*w->step;
19210 break;
19211 case r_down:
19212 case r_up:
19213 case right:
19214 vx = w->step;
19215 break;
19216
19217 default:
19218 vx = 0;
19219 break;
19220 }
19221 switch(NORMAL_DIR(w->dir))
19222 {
19223 case l_up:
19224 case r_up:
19225 case up:
19226 vy = -1.0*w->step;
19227 break;
19228 case l_down:
19229 case r_down:
19230 case down:
19231 vy = w->step;
19232 break;
19233
19234 default:
19235 vy = 0;
19236 break;
19237 }
19238 w->angular = true;
19239 w->angle=atan2(vy, vx);
19240 w->step=FFCore.Distance(0, 0, vx, vy)/10000.0;
19241 w->doAutoRotate();
19242 }
19243 }
19244 }
19245
19246 void do_lwpnmakedirectional()
19247 {
19248 if(LwpnH::loadWeapon(GET_REF(lwpnref)) == SH::_NoError)
19249 {
19250 if (LwpnH::getWeapon()->angular)
19251 {
19252 LwpnH::getWeapon()->dir = NORMAL_DIR(AngleToDir(WrapAngle(LwpnH::getWeapon()->angle)));
19253 LwpnH::getWeapon()->angular = false;
19254 LwpnH::getWeapon()->doAutoRotate(true);
19255 }
19256 }
19257 }
19258
19259 void do_ewpnmakeangular()
19260 {
19261 if(EwpnH::loadWeapon(GET_REF(ewpnref)) == SH::_NoError)
19262 {
19263 auto w = EwpnH::getWeapon();
19264 if (!w->angular)
19265 {
19266 double vx;
19267 double vy;
19268 switch(NORMAL_DIR(w->dir))
19269 {
19270 case l_up:
19271 case l_down:
19272 case left:
19273 vx = -1.0*w->step;
19274 break;
19275 case r_down:
19276 case r_up:
19277 case right:
19278 vx = w->step;
19279 break;
19280
19281 default:
19282 vx = 0;
19283 break;
19284 }
19285 switch(NORMAL_DIR(w->dir))
19286 {
19287 case l_up:
19288 case r_up:
19289 case up:
19290 vy = -1.0*w->step;
19291 break;
19292 case l_down:
19293 case r_down:
19294 case down:
19295 vy = w->step;
19296 break;
19297
19298 default:
19299 vy = 0;
19300 break;
19301 }
19302 w->angular = true;
19303 w->angle=atan2(vy, vx);
19304 w->step=FFCore.Distance(0, 0, vx, vy)/10000.0;
19305 w->doAutoRotate();
19306 }
19307 }
19308 }
19309
19310 void do_ewpnmakedirectional()
19311 {
19312 if(EwpnH::loadWeapon(GET_REF(lwpnref)) == SH::_NoError)
19313 {
19314 if (EwpnH::getWeapon()->angular)
19315 {
19316 EwpnH::getWeapon()->dir = NORMAL_DIR(AngleToDir(WrapAngle(EwpnH::getWeapon()->angle)));
19317 EwpnH::getWeapon()->angular = false;
19318 EwpnH::getWeapon()->doAutoRotate(true);
19319 }
19320 }
19321 }
19322
19323 20064 void do_lwpnusesprite(const bool v)
19324 {
19325 20064 int32_t ID = SH::get_arg(sarg1, v) / 10000;
19326
19327
1/2
✓ Branch 0 taken 20064 times.
✗ Branch 1 not taken.
20064 if(BC::checkWeaponMiscSprite(ID) != SH::_NoError)
19328 return;
19329
19330
1/2
✓ Branch 0 taken 20064 times.
✗ Branch 1 not taken.
20064 if(LwpnH::loadWeapon(GET_REF(lwpnref)) == SH::_NoError)
19331 20064 LwpnH::getWeapon()->LOADGFX(ID);
19332 20064 }
19333
19334 296065 void do_ewpnusesprite(const bool v)
19335 {
19336 296065 int32_t ID = SH::get_arg(sarg1, v) / 10000;
19337
19338
1/2
✓ Branch 0 taken 296065 times.
✗ Branch 1 not taken.
296065 if(BC::checkWeaponMiscSprite(ID) != SH::_NoError)
19339 return;
19340
19341
1/2
✓ Branch 0 taken 296065 times.
✗ Branch 1 not taken.
296065 if(EwpnH::loadWeapon(GET_REF(ewpnref)) == SH::_NoError)
19342 296065 EwpnH::getWeapon()->LOADGFX(ID);
19343 296065 }
19344
19345 void do_portalusesprite()
19346 {
19347 int32_t ID = get_register(sarg1) / 10000;
19348
19349 if(BC::checkWeaponMiscSprite(ID) != SH::_NoError)
19350 return;
19351
19352 if(portal* p = checkPortal(GET_REF(portalref)))
19353 p->LOADGFX(ID);
19354 }
19355
19356 void do_clearsprites(const bool v)
19357 {
19358 int32_t spritelist = SH::get_arg(sarg1, v) / 10000;
19359
19360 if(BC::checkBounds(spritelist, 0, 5) != SH::_NoError)
19361 return;
19362
19363 switch(spritelist)
19364 {
19365 case 0:
19366 guys.clear();
19367 break;
19368
19369 case 1:
19370 items.clear();
19371 break;
19372
19373 case 2:
19374 Ewpns.clear();
19375 break;
19376
19377 case 3:
19378 Lwpns.clear();
19379 Hero.reset_hookshot();
19380 break;
19381
19382 case 4:
19383 decorations.clear();
19384 break;
19385
19386 case 5:
19387 particles.clear();
19388 break;
19389 }
19390 }
19391
19392 1860392 void do_loadlweapon(const bool v)
19393 {
19394 1860392 int32_t index = SH::get_arg(sarg1, v) / 10000;
19395
19396
2/2
✓ Branch 0 taken 16630 times.
✓ Branch 1 taken 1843762 times.
1860392 if(BC::checkLWeaponIndex(index) != SH::_NoError)
19397 16630 ri->lwpnref = 0; //MAX_DWORD; //Now NULL
19398 else
19399 {
19400 1843762 ri->lwpnref = Lwpns.spr(index)->getUID();
19401 // This is too trivial to log. -L
19402 }
19403 1860392 }
19404
19405 5661515 void do_loadeweapon(const bool v)
19406 {
19407 5661515 int32_t index = SH::get_arg(sarg1, v) / 10000;
19408
19409
2/2
✓ Branch 0 taken 68863 times.
✓ Branch 1 taken 5592652 times.
5661515 if(BC::checkEWeaponIndex(index) != SH::_NoError)
19410 68863 ri->ewpnref = 0; //MAX_DWORD; //Now NULL
19411 else
19412 {
19413 5592652 ri->ewpnref = Ewpns.spr(index)->getUID();
19414 }
19415 5661515 }
19416
19417 585769 void do_loaditem(const bool v)
19418 {
19419 585769 int32_t index = SH::get_arg(sarg1, v) / 10000;
19420
19421
2/2
✓ Branch 0 taken 298944 times.
✓ Branch 1 taken 286825 times.
585769 if(BC::checkItemIndex(index) != SH::_NoError)
19422 298944 ri->itemref = 0; //MAX_DWORD; //Now NULL
19423 else
19424 {
19425 286825 ri->itemref = items.spr(index)->getUID();
19426 }
19427 585769 }
19428
19429
19430 58103417 void do_loaditemdata(const bool v)
19431 {
19432 58103417 int32_t ID = SH::get_arg(sarg1, v) / 10000;
19433
19434 //I *think* this is the right check ~Joe
19435
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58103417 times.
58103417 if(BC::checkItemID(ID) != SH::_NoError)
19436 {
19437 ri->itemdataref = -1; //new null value
19438 return;
19439 }
19440 58103417 ri->itemdataref = ID;
19441 58103417 }
19442
19443 32179030 void do_loadnpc(const bool v)
19444 {
19445 32179030 int32_t index = SH::get_arg(sarg1, v) / 10000;
19446
19447
2/2
✓ Branch 0 taken 204 times.
✓ Branch 1 taken 32178826 times.
32179030 if(BC::checkGuyIndex(index) != SH::_NoError)
19448 204 ri->npcref = 0; // MAX_DWORD;
19449 else
19450 {
19451 32178826 ri->npcref = guys.spr(index)->getUID();
19452 }
19453 32179030 }
19454
19455 1746835 void FFScript::do_loaddmapdata(const bool v)
19456 {
19457 1746835 int32_t ID = SH::get_arg(sarg1, v) / 10000;
19458
19459
2/4
✓ Branch 0 taken 1746835 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1746835 times.
1746835 if ( ID < 0 || ID > 511 )
19460 {
19461 Z_scripterrlog("Invalid DMap ID passed to Game->LoadDMapData(): %d\n", ID);
19462 ri->dmapdataref = MAX_DWORD;
19463 }
19464 1746835 else ri->dmapdataref = ID;
19465 1746835 }
19466
19467 3 void FFScript::do_load_active_subscreendata(const bool v)
19468 {
19469 3 int32_t ID = SH::get_arg(sarg1, v) / 10000;
19470
19471
3/6
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 if(ID == -1 || (unsigned(ID) < subscreens_active.size() && unsigned(ID) < 256))
19472 {
19473 3 ri->subscreendataref = get_subref(ID, sstACTIVE);
19474 3 }
19475 else
19476 {
19477 Z_scripterrlog("Invalid Subscreen ID passed to Game->LoadASubData(): %d\n", ID);
19478 ri->subscreendataref = 0;
19479 }
19480 3 SET_D(rEXP1, ri->subscreendataref);
19481 3 }
19482 void FFScript::do_load_passive_subscreendata(const bool v)
19483 {
19484 int32_t ID = SH::get_arg(sarg1, v) / 10000;
19485
19486 if(ID == -1 || (unsigned(ID) < subscreens_passive.size() && unsigned(ID) < 256))
19487 {
19488 ri->subscreendataref = get_subref(ID, sstPASSIVE);
19489 }
19490 else
19491 {
19492 Z_scripterrlog("Invalid Subscreen ID passed to Game->LoadPSubData(): %d\n", ID);
19493 ri->subscreendataref = 0;
19494 }
19495 SET_D(rEXP1, ri->subscreendataref);
19496 }
19497 void FFScript::do_load_overlay_subscreendata(const bool v)
19498 {
19499 int32_t ID = SH::get_arg(sarg1, v) / 10000;
19500
19501 if(ID == -1 || (unsigned(ID) < subscreens_overlay.size() && unsigned(ID) < 256))
19502 {
19503 ri->subscreendataref = get_subref(ID, sstOVERLAY);
19504 }
19505 else
19506 {
19507 Z_scripterrlog("Invalid Subscreen ID passed to Game->LoadOSubData(): %d\n", ID);
19508 ri->subscreendataref = 0;
19509 }
19510 SET_D(rEXP1, ri->subscreendataref);
19511 }
19512 void FFScript::do_load_map_subscreendata(const bool v)
19513 {
19514 int32_t ID = SH::get_arg(sarg1, v) / 10000;
19515
19516 if(ID == -1 || (unsigned(ID) < subscreens_map.size() && unsigned(ID) < 256))
19517 {
19518 ri->subscreendataref = get_subref(ID, sstACTIVE);
19519 }
19520 else
19521 {
19522 Z_scripterrlog("Invalid Subscreen ID passed to Game->LoadMSubData(): %d\n", ID);
19523 ri->subscreendataref = 0;
19524 }
19525 SET_D(rEXP1, ri->subscreendataref);
19526 }
19527 3 void FFScript::do_load_subscreendata(const bool v, const bool v2)
19528 {
19529 3 int32_t ty = SH::get_arg(sarg2, v2) / 10000;
19530
1/5
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
3 switch(ty)
19531 {
19532 case sstACTIVE:
19533 3 do_load_active_subscreendata(v);
19534 3 break;
19535 case sstPASSIVE:
19536 do_load_passive_subscreendata(v);
19537 break;
19538 case sstOVERLAY:
19539 do_load_overlay_subscreendata(v);
19540 break;
19541 case sstMAP:
19542 do_load_map_subscreendata(v);
19543 break;
19544 default:
19545 {
19546 Z_scripterrlog("Invalid Subscreen Type passed to ???: %d\n", ty);
19547 ri->subscreendataref = 0;
19548 break;
19549 }
19550 }
19551 3 SET_D(rEXP1, ri->subscreendataref);
19552 3 }
19553
19554 932 void FFScript::do_loadrng()
19555 {
19556 932 auto rng = user_rngs.create();
19557
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 932 times.
932 if (!rng)
19558 {
19559 SET_D(rEXP1, 0);
19560 return;
19561 }
19562
19563 932 int q = script_object_ids_by_type[script_object_type::rng].size() - 1;
19564 932 rng->gen = &script_rnggens[q];
19565 932 ri->rngref = rng->id;
19566 932 SET_D(rEXP1, rng->id);
19567 932 }
19568
19569 void FFScript::do_loadstack()
19570 {
19571 ri->stackref = user_stacks.get_free();
19572 SET_D(rEXP1, ri->stackref);
19573 }
19574
19575 10 void FFScript::do_loaddropset(const bool v)
19576 {
19577 10 int32_t ID = SH::get_arg(sarg1, v) / 10000;
19578
19579
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
10 if ( ID < 0 || ID > MAXITEMDROPSETS )
19580 {
19581 scripting_log_error_with_context("Invalid Dropset ID: {}", ID);
19582 ri->dropsetdataref = MAX_DWORD;
19583 }
19584
19585 10 else ri->dropsetdataref = ID;
19586 10 }
19587
19588 void FFScript::do_loadbottle(const bool v)
19589 {
19590 int32_t ID = SH::get_arg(sarg1, v) / 10000;
19591
19592 if ( ID < 1 || ID > 64 )
19593 {
19594 scripting_log_error_with_context("Invalid BottleType ID: {}", ID);
19595 ri->bottletyperef = 0;
19596 }
19597 else ri->bottletyperef = ID;
19598 }
19599
19600 void FFScript::do_loadbottleshop(const bool v)
19601 {
19602 int32_t ID = SH::get_arg(sarg1, v) / 10000;
19603
19604 if ( ID < 0 || ID > 255 )
19605 {
19606 scripting_log_error_with_context("Invalid BottleShopType ID: {}", ID);
19607 ri->bottleshopref = 0;
19608 }
19609 else ri->bottleshopref = ID+1;
19610 }
19611 137140 void FFScript::do_loadgenericdata(const bool v)
19612 {
19613 137140 int32_t ID = SH::get_arg(sarg1, v) / 10000;
19614
19615
2/4
✓ Branch 0 taken 137140 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 137140 times.
137140 if ( ID < 1 || ID > NUMSCRIPTSGENERIC )
19616 {
19617 scripting_log_error_with_context("Invalid GenericData ID: {}", ID);
19618 ri->genericdataref = 0;
19619 }
19620 137140 else ri->genericdataref = ID;
19621 137140 }
19622
19623 223 void FFScript::do_create_paldata()
19624 {
19625 223 ri->paldataref = user_paldatas.get_free();
19626 223 SET_D(rEXP1, ri->paldataref);
19627 223 }
19628
19629 11 void FFScript::do_create_paldata_clr()
19630 {
19631 11 ri->paldataref = user_paldatas.get_free();
19632
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (ri->paldataref > 0)
19633 {
19634 11 user_paldata& pd = user_paldatas[GET_REF(paldataref)];
19635 11 int32_t clri = get_register(sarg1);
19636
19637 11 RGB c = _RGB((clri >> 16) & 0xFF, (clri >> 8) & 0xFF, clri & 0xFF);
19638
19639 11 c.r = vbound(c.r, 0, scripting_max_color_val);
19640 11 c.g = vbound(c.g, 0, scripting_max_color_val);
19641 11 c.b = vbound(c.b, 0, scripting_max_color_val);
19642
19643
2/2
✓ Branch 0 taken 2640 times.
✓ Branch 1 taken 11 times.
2651 for (int32_t q = 0; q < 240; ++q)
19644 2640 pd.set_color(q, c);
19645 11 }
19646 11 SET_D(rEXP1, ri->paldataref);
19647 11 }
19648
19649 void FFScript::do_mix_clr()
19650 {
19651 int32_t clr_start = SH::read_stack(ri->sp + 3);
19652 int32_t clr_end = SH::read_stack(ri->sp + 2);
19653 float percent = SH::read_stack(ri->sp + 1) / 10000.0;
19654 int32_t color_space = SH::read_stack(ri->sp + 0) / 10000;
19655
19656 RGB ref1c = _RGB((clr_start >> 16) & 0xFF, (clr_start >> 8) & 0xFF, clr_start & 0xFF);
19657 RGB ref2c = _RGB((clr_end >> 16) & 0xFF, (clr_end >> 8) & 0xFF, clr_end & 0xFF);
19658 RGB outputc = user_paldata::mix_color(ref1c, ref2c, percent, color_space);
19659
19660 int32_t r = vbound(outputc.r, 0, scripting_max_color_val);
19661 int32_t g = vbound(outputc.g, 0, scripting_max_color_val);
19662 int32_t b = vbound(outputc.b, 0, scripting_max_color_val);
19663
19664 SET_D(rEXP1, (r << 16) | (g << 8) | b);
19665 }
19666
19667 void FFScript::do_create_rgb_hex()
19668 {
19669 int32_t hexrgb = get_register(sarg1);
19670
19671 int32_t r = (hexrgb >> 16) & 0xFF;
19672 int32_t g = (hexrgb >> 8) & 0xFF;
19673 int32_t b = hexrgb & 0xFF;
19674
19675 if (scripting_use_8bit_colors)
19676 {
19677 r = vbound(r, 0, 255);
19678 g = vbound(g, 0, 255);
19679 b = vbound(b, 0, 255);
19680 }
19681 else
19682 {
19683 r = vbound(r / 4, 0, 63);
19684 g = vbound(g / 4, 0, 63);
19685 b = vbound(b / 4, 0, 63);
19686 }
19687
19688 SET_D(rEXP1, (r << 16) | (g << 8) | b);
19689 }
19690
19691 11 void FFScript::do_create_rgb()
19692 {
19693 11 int32_t r = SH::read_stack(ri->sp + 2) / 10000;
19694 11 int32_t g = SH::read_stack(ri->sp + 1) / 10000;
19695 11 int32_t b = SH::read_stack(ri->sp + 0) / 10000;
19696
19697 11 int max_value = scripting_max_color_val;
19698
4/6
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 10 times.
11 if (unsigned(r) > max_value || unsigned(g) > max_value || unsigned(b) > max_value)
19699 {
19700 1 scripting_log_error_with_context("R/G/B values should range from 0-{}, got: {} {} {}", max_value, r, g, b);
19701 1 }
19702
19703 11 r = vbound(r, 0, max_value);
19704 11 g = vbound(g, 0, max_value);
19705 11 b = vbound(b, 0, max_value);
19706
19707 11 SET_D(rEXP1, (r << 16) | (g << 8) | b);
19708 11 }
19709
19710 void FFScript::do_convert_from_rgb()
19711 {
19712 int32_t buf = SH::read_stack(ri->sp + 2) / 10000;
19713 int32_t clri = SH::read_stack(ri->sp + 1);
19714 int32_t color_space = SH::read_stack(ri->sp + 0) / 10000;
19715
19716 ArrayManager am(buf);
19717 if (am.invalid()) return;
19718 int32_t zscript_array_size = am.size();
19719 int32_t target_size;
19720
19721 switch (color_space)
19722 {
19723 case user_paldata::CSPACE_CMYK:
19724 target_size = 4;
19725 break;
19726 default:
19727 target_size = 3;
19728 }
19729
19730 if (zscript_array_size < target_size)
19731 {
19732 scripting_log_error_with_context("Array not large enough. Should be at least size {}", target_size);
19733 return;
19734 }
19735
19736 RGB c = _RGB((clri >> 16) & 0xFF, (clri >> 8) & 0xFF, clri & 0xFF);
19737 double convert[4];
19738 user_paldata::RGBTo(c, convert, color_space);
19739
19740 for (int32_t q = 0; q < target_size; ++q)
19741 {
19742 am.set(q, int32_t(convert[q]*10000));
19743 }
19744
19745 return;
19746 }
19747
19748 void FFScript::do_convert_to_rgb()
19749 {
19750 int32_t buf = SH::read_stack(ri->sp + 1) / 10000;
19751 int32_t color_space = SH::read_stack(ri->sp + 0) / 10000;
19752
19753 ArrayManager am(buf);
19754 if (am.invalid()) return;
19755 int32_t zscript_array_size = am.size();
19756 int32_t target_size;
19757
19758 switch (color_space)
19759 {
19760 case user_paldata::CSPACE_CMYK:
19761 target_size = 4;
19762 break;
19763 default:
19764 target_size = 3;
19765 }
19766
19767 if (zscript_array_size < target_size)
19768 {
19769 scripting_log_error_with_context("Array not large enough. Should be at least size {}", target_size);
19770 return;
19771 }
19772
19773 double convert[4];
19774 for (int32_t q = 0; q < target_size; ++q)
19775 {
19776 convert[q] = am.get(q) / 10000.0;
19777 }
19778 RGB c = user_paldata::RGBFrom(convert, color_space);
19779
19780 SET_D(rEXP1, (c.r << 16) | (c.g << 8) | c.b);
19781 }
19782
19783 24 void FFScript::do_paldata_load_level()
19784 {
19785
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
19786 {
19787 24 int32_t lvl = get_register(sarg1) / 10000;
19788 //Load CSets 2-4
19789 24 pd->load_cset(2, lvl * pdLEVEL + poLEVEL + 0);
19790 24 pd->load_cset(3, lvl * pdLEVEL + poLEVEL + 1);
19791 24 pd->load_cset(4, lvl * pdLEVEL + poLEVEL + 2);
19792 //Load CSet 9
19793 24 pd->load_cset(9, lvl * pdLEVEL + poLEVEL + 3);
19794 //Load 1, 5, 7, 8
19795 24 pd->load_cset(1, lvl * pdLEVEL + poNEWCSETS);
19796 24 pd->load_cset(5, lvl * pdLEVEL + poNEWCSETS + 1);
19797 24 pd->load_cset(7, lvl * pdLEVEL + poNEWCSETS + 2);
19798 24 pd->load_cset(8, lvl * pdLEVEL + poNEWCSETS + 3);
19799 24 }
19800 24 return;
19801 }
19802
19803 87 void FFScript::do_paldata_load_sprite()
19804 {
19805
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 87 times.
87 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
19806 {
19807 87 int32_t page = get_register(sarg1) / 10000;
19808
19809 87 int32_t pageoffset = 0;
19810
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 87 times.
✗ Branch 2 not taken.
87 switch (page)
19811 {
19812 87 case 0: pageoffset += 0; break;
19813 case 1: pageoffset += 15; break;
19814 default:
19815 scripting_log_error_with_context("Invalid page: {}. Valid pages are 0 or 1. Aborting.", page);
19816 return;
19817 }
19818
2/2
✓ Branch 0 taken 1305 times.
✓ Branch 1 taken 87 times.
1392 for (int32_t q = 0; q < 15; ++q)
19819 {
19820 1305 pd->load_cset(q, poSPRITE255 + pageoffset + q);
19821 1305 }
19822 87 }
19823 87 return;
19824 87 }
19825
19826 92 void FFScript::do_paldata_load_main()
19827 {
19828
1/2
✓ Branch 0 taken 92 times.
✗ Branch 1 not taken.
92 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
19829 {
19830
2/2
✓ Branch 0 taken 1472 times.
✓ Branch 1 taken 92 times.
1564 for (int32_t q = 0; q <= 15; ++q)
19831 {
19832 1472 pd->load_cset_main(q);
19833 1472 }
19834 92 }
19835 92 return;
19836 }
19837
19838 void FFScript::do_paldata_load_cycle()
19839 {
19840 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
19841 {
19842 int32_t lvl = get_register(sarg1) / 10000;
19843 for (int32_t q = 4; q <= 12; ++q)
19844 {
19845 pd->load_cset(q, lvl * pdLEVEL + poLEVEL + q);
19846 }
19847 }
19848 return;
19849 }
19850
19851 void FFScript::do_paldata_load_bitmap()
19852 {
19853 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
19854 {
19855 int32_t pathptr = get_register(sarg1);
19856 string user_path, str;
19857 ArrayH::getString(pathptr, user_path, 256);
19858
19859 if (get_qr(qr_BITMAP_AND_FILESYSTEM_PATHS_ALWAYS_RELATIVE))
19860 {
19861 if (auto r = parse_user_path(user_path, true); !r)
19862 {
19863 scripting_log_error_with_context("Error: {}", r.error());
19864 return;
19865 } else str = r.value();
19866 }
19867 else
19868 {
19869 str = user_path;
19870 regulate_path(str);
19871 }
19872
19873 if (str.empty())
19874 {
19875 al_trace("String pointer is null! Internal error. \n");
19876 return;
19877 }
19878
19879 PALETTE tempPal;
19880 get_palette(tempPal);
19881 if (checkPath(str.c_str(), false))
19882 {
19883 BITMAP* bmp = load_bitmap(str.c_str(), tempPal);
19884 if (!bmp)
19885 {
19886 Z_scripterrlog("LoadBitmapPalette() failed to load image file %s.\n", str.c_str());
19887 }
19888 else
19889 {
19890 for (int32_t q = 0; q < PALDATA_NUM_COLORS; ++q)
19891 {
19892 pd->colors[q] = tempPal[q];
19893 set_bit(pd->colors_used, q, true);
19894 }
19895 }
19896 destroy_bitmap(bmp);
19897 }
19898 else
19899 {
19900 Z_scripterrlog("Failed to load image file: %s. File not found.\n", str.c_str());
19901 }
19902 }
19903 return;
19904 }
19905
19906 370 void FFScript::do_paldata_write_level()
19907 {
19908
1/2
✓ Branch 0 taken 370 times.
✗ Branch 1 not taken.
370 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
19909 {
19910 370 int32_t lvl = get_register(sarg1) / 10000;
19911 370 bool changed = false;
19912 //Write CSets 2-4
19913
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 360 times.
370 if (pd->check_cset(2, lvl * pdLEVEL + poLEVEL + 0))
19914 {
19915 360 pd->write_cset(2, lvl * pdLEVEL + poLEVEL + 0);
19916 360 changed = true;
19917 360 }
19918
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 360 times.
370 if (pd->check_cset(3, lvl * pdLEVEL + poLEVEL + 1))
19919 {
19920 360 pd->write_cset(3, lvl * pdLEVEL + poLEVEL + 1);
19921 360 changed = true;
19922 360 }
19923
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 360 times.
370 if (pd->check_cset(4, lvl * pdLEVEL + poLEVEL + 2))
19924 {
19925 360 pd->write_cset(4, lvl * pdLEVEL + poLEVEL + 2);
19926 360 changed = true;
19927 360 }
19928 //Write CSet 9
19929
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 360 times.
370 if (pd->check_cset(9, lvl * pdLEVEL + poLEVEL + 3))
19930 {
19931 360 pd->write_cset(9, lvl * pdLEVEL + poLEVEL + 3);
19932 360 changed = true;
19933 360 }
19934 //Write 1, 5, 7, 8
19935
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 360 times.
370 if (pd->check_cset(1, lvl * pdLEVEL + poNEWCSETS + 0))
19936 {
19937 360 pd->write_cset(1, lvl * pdLEVEL + poNEWCSETS + 0);
19938 360 changed = true;
19939 360 }
19940
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 360 times.
370 if (pd->check_cset(5, lvl * pdLEVEL + poNEWCSETS + 1))
19941 {
19942 360 pd->write_cset(5, lvl * pdLEVEL + poNEWCSETS + 1);
19943 360 changed = true;
19944 360 }
19945
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 360 times.
370 if (pd->check_cset(7, lvl * pdLEVEL + poNEWCSETS + 2))
19946 {
19947 360 pd->write_cset(7, lvl * pdLEVEL + poNEWCSETS + 2);
19948 360 changed = true;
19949 360 }
19950
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 360 times.
370 if (pd->check_cset(8, lvl * pdLEVEL + poNEWCSETS + 3))
19951 {
19952 360 pd->write_cset(8, lvl * pdLEVEL + poNEWCSETS + 3);
19953 360 changed = true;
19954 360 }
19955
19956
4/4
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 350 times.
370 if (changed && DMaps[cur_dmap].color == lvl)
19957 {
19958 350 loadlvlpal(lvl);
19959 350 currcset = lvl;
19960
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 350 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
350 if (darkroom && !get_qr(qr_NEW_DARKROOM))
19961 {
19962 if (get_qr(qr_FADE))
19963 {
19964 interpolatedfade();
19965 }
19966 else
19967 {
19968 loadfadepal((DMaps[cur_dmap].color) * pdLEVEL + poFADE3);
19969 }
19970 }
19971 350 }
19972 370 }
19973 370 return;
19974 }
19975
19976 void FFScript::do_paldata_write_levelcset()
19977 {
19978 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
19979 {
19980 int32_t lvl = get_register(sarg1) / 10000;
19981 int32_t cs = get_register(sarg2) / 10000;
19982
19983 bool changed = false;
19984
19985 switch (cs)
19986 {
19987 case 1:
19988 if (pd->check_cset(1, lvl * pdLEVEL + poNEWCSETS + 0))
19989 {
19990 pd->write_cset(1, lvl * pdLEVEL + poNEWCSETS + 0);
19991 changed = true;
19992 }
19993 break;
19994 case 2:
19995 if (pd->check_cset(2, lvl * pdLEVEL + poLEVEL + 0))
19996 {
19997 pd->write_cset(2, lvl * pdLEVEL + poLEVEL + 0);
19998 changed = true;
19999 }
20000 break;
20001 case 3:
20002 if (pd->check_cset(3, lvl * pdLEVEL + poLEVEL + 1))
20003 {
20004 pd->write_cset(3, lvl * pdLEVEL + poLEVEL + 1);
20005 changed = true;
20006 }
20007 break;
20008 case 4:
20009 if (pd->check_cset(4, lvl * pdLEVEL + poLEVEL + 2))
20010 {
20011 pd->write_cset(4, lvl * pdLEVEL + poLEVEL + 2);
20012 changed = true;
20013 }
20014 break;
20015 case 5:
20016 if (pd->check_cset(5, lvl * pdLEVEL + poNEWCSETS + 1))
20017 {
20018 pd->write_cset(5, lvl * pdLEVEL + poNEWCSETS + 1);
20019 changed = true;
20020 }
20021 break;
20022 case 7:
20023 if (pd->check_cset(7, lvl * pdLEVEL + poNEWCSETS + 2))
20024 {
20025 pd->write_cset(7, lvl * pdLEVEL + poNEWCSETS + 2);
20026 changed = true;
20027 }
20028 break;
20029 case 8:
20030 if (pd->check_cset(8, lvl * pdLEVEL + poNEWCSETS + 3))
20031 {
20032 pd->write_cset(8, lvl * pdLEVEL + poNEWCSETS + 3);
20033 changed = true;
20034 }
20035 break;
20036 case 9:
20037 if (pd->check_cset(9, lvl * pdLEVEL + poLEVEL + 3))
20038 {
20039 pd->write_cset(9, lvl * pdLEVEL + poLEVEL + 3);
20040 changed = true;
20041 }
20042 break;
20043 default:
20044 Z_scripterrlog("Invalid CSet (%d) passed to 'paldata->WriteLevelCSet()'. Level palettes can use CSets 1, 2, 3, 4, 5, 7, 8, 9.\n", cs);
20045 return;
20046 }
20047
20048 if (changed && DMaps[cur_dmap].color == lvl)
20049 {
20050 loadlvlpal(lvl);
20051 if (darkroom && !get_qr(qr_NEW_DARKROOM))
20052 {
20053 if (get_qr(qr_FADE))
20054 {
20055 interpolatedfade();
20056 }
20057 else
20058 {
20059 loadfadepal((DMaps[cur_dmap].color) * pdLEVEL + poFADE3);
20060 }
20061 }
20062 currcset = lvl;
20063 }
20064 }
20065 }
20066
20067 31 void FFScript::do_paldata_write_sprite()
20068 {
20069
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
20070 {
20071 31 int32_t page = get_register(sarg1) / 10000;
20072
20073 31 int32_t pageoffset = 0;
20074
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
✗ Branch 2 not taken.
31 switch (page)
20075 {
20076 31 case 0: pageoffset += 0; break;
20077 case 1: pageoffset += 15; break;
20078 default:
20079 Z_scripterrlog("Invalid page (%d) passed to paldata->WriteSpritePalette(). Valid pages are 0 or 1. Aborting.\n", page);
20080 return;
20081 }
20082 31 bool changed6 = false;
20083 31 bool changed14 = false;
20084
2/2
✓ Branch 0 taken 465 times.
✓ Branch 1 taken 31 times.
496 for (int32_t q = 0; q < 15; ++q)
20085 {
20086
2/2
✓ Branch 0 taken 440 times.
✓ Branch 1 taken 25 times.
465 if (pd->check_cset(q, poSPRITE255 + pageoffset + q))
20087 {
20088 25 pd->write_cset(q, poSPRITE255 + pageoffset + q);
20089
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 if (pageoffset + q == currspal6)
20090 {
20091 changed6 = true;
20092 }
20093
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 if (pageoffset + q == currspal14)
20094 {
20095 changed14 = true;
20096 }
20097 25 }
20098 465 }
20099
20100 //If either sprite palette has been changed, update the main palette
20101
2/4
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 31 times.
31 if (changed6 || changed14)
20102 {
20103 if (changed6)
20104 {
20105 loadpalset(6, poSPRITE255 + currspal6, false);
20106 }
20107 if (changed14)
20108 {
20109 loadpalset(14, poSPRITE255 + currspal14, false);
20110 }
20111
20112 if (isUserTinted()) {
20113 restoreTint();
20114 }
20115 }
20116 31 }
20117 31 return;
20118 31 }
20119
20120 void FFScript::do_paldata_write_spritecset()
20121 {
20122 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
20123 {
20124 int32_t page = get_register(sarg1) / 10000;
20125 int32_t cs = get_register(sarg2) / 10000;
20126
20127 int32_t pageoffset = 0;
20128 switch (page)
20129 {
20130 case 0: pageoffset += 0; break;
20131 case 1: pageoffset += 15; break;
20132 default:
20133 Z_scripterrlog("Invalid page (%d) passed to paldata->WriteSpriteCSet(). Valid pages are 0 or 1. Aborting.\n", page);
20134 return;
20135 }
20136 bool changed6 = false;
20137 bool changed14 = false;
20138 if (unsigned(cs) > 15)
20139 {
20140 Z_scripterrlog("Invalid CSet (%d) passed to paldata->WriteSpriteCSet(). Valid CSets are 0-15. Aborting.\n", cs);
20141 return;
20142 }
20143 if (pd->check_cset(cs, poSPRITE255 + pageoffset + cs))
20144 {
20145 pd->write_cset(cs, poSPRITE255 + pageoffset + cs);
20146 if (pageoffset + cs == currspal6)
20147 {
20148 changed6 = true;
20149 }
20150 if (pageoffset + cs == currspal14)
20151 {
20152 changed14 = true;
20153 }
20154 }
20155
20156 //If either sprite palette has been changed, update the main palette
20157 if (changed6 || changed14)
20158 {
20159 if (changed6)
20160 {
20161 loadpalset(6, poSPRITE255 + currspal6, false);
20162 }
20163 if (changed14)
20164 {
20165 loadpalset(14, poSPRITE255 + currspal14, false);
20166 }
20167
20168 if (isUserTinted()) {
20169 restoreTint();
20170 }
20171 }
20172 }
20173 return;
20174 }
20175
20176 1064 void FFScript::do_paldata_write_main()
20177 {
20178
1/2
✓ Branch 0 taken 1064 times.
✗ Branch 1 not taken.
1064 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
20179 {
20180 1064 bool changed = false;
20181
2/2
✓ Branch 0 taken 17024 times.
✓ Branch 1 taken 1064 times.
18088 for (int32_t q = 0; q <= 15; ++q)
20182 {
20183
2/2
✓ Branch 0 taken 11363 times.
✓ Branch 1 taken 5661 times.
17024 if (pd->check_cset_main(q))
20184 {
20185 5661 pd->write_cset_main(q);
20186 5661 changed = true;
20187 5661 }
20188 17024 }
20189
20190
2/2
✓ Branch 0 taken 332 times.
✓ Branch 1 taken 732 times.
1064 if (changed)
20191 {
20192 732 refreshpal = true;
20193 732 }
20194 1064 }
20195 1064 return;
20196 }
20197
20198 130 void FFScript::do_paldata_write_maincset()
20199 {
20200
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 130 times.
130 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
20201 {
20202 130 int32_t cs = get_register(sarg1) / 10000;
20203
20204 130 bool changed = false;
20205
20206
1/2
✓ Branch 0 taken 130 times.
✗ Branch 1 not taken.
130 if (unsigned(cs) < 16)
20207 {
20208
1/2
✓ Branch 0 taken 130 times.
✗ Branch 1 not taken.
130 if (pd->check_cset_main(cs))
20209 {
20210 130 pd->write_cset_main(cs);
20211 130 changed = true;
20212 130 }
20213 130 }
20214 else
20215 {
20216 Z_scripterrlog("Invalid CSet (%d) passed to 'paldata->WriteMainCSet()'. Valid csets are 0-15. Aborting.\n", cs);
20217 return;
20218 }
20219
20220
1/2
✓ Branch 0 taken 130 times.
✗ Branch 1 not taken.
130 if (changed)
20221 {
20222 130 refreshpal = true;
20223 130 }
20224 130 }
20225 130 }
20226
20227 void FFScript::do_paldata_write_cycle()
20228 {
20229 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
20230 {
20231 int32_t lvl = get_register(sarg1) / 10000;
20232 for (int32_t q = 4; q <= 12; ++q)
20233 {
20234 if (pd->check_cset(q, lvl * pdLEVEL + poLEVEL + q))
20235 {
20236 pd->write_cset(q, lvl * pdLEVEL + poLEVEL + q);
20237 }
20238 }
20239 }
20240 return;
20241 }
20242
20243 void FFScript::do_paldata_write_cyclecset()
20244 {
20245 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
20246 {
20247 int32_t lvl = get_register(sarg1) / 10000;
20248 int32_t cs = get_register(sarg2) / 10000;
20249
20250 bool changed = false;
20251
20252 switch (cs)
20253 {
20254 case 4:
20255 case 5:
20256 case 6:
20257 case 7:
20258 case 8:
20259 case 9:
20260 case 10:
20261 case 11:
20262 case 12:
20263 if (pd->check_cset(cs, lvl * pdLEVEL + poLEVEL + cs))
20264 {
20265 pd->write_cset(cs, lvl * pdLEVEL + poLEVEL + cs);
20266 changed = true;
20267 }
20268 break;
20269 default:
20270 Z_scripterrlog("Invalid CSet (%d) passed to 'paldata->WriteCycleCSet()'. Cycle palettes use CSets 4-12.\n", cs);
20271 return;
20272 }
20273
20274 if (changed && DMaps[cur_dmap].color == lvl)
20275 {
20276 loadlvlpal(lvl);
20277 currcset = lvl;
20278 }
20279 }
20280 }
20281
20282 void FFScript::do_paldata_colorvalid()
20283 {
20284 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
20285 {
20286 int32_t ind = get_register(sarg1) / 10000;
20287 if (unsigned(ind) >= PALDATA_NUM_COLORS)
20288 {
20289 Z_scripterrlog("Invalid color index (%d) passed to paldata->ColorValid(). Valid indices are 0-255.\n", ind);
20290 set_register(sarg1, 0);
20291 return;
20292 }
20293
20294 if (get_bit(pd->colors_used, ind))
20295 {
20296 set_register(sarg1, 10000);
20297 }
20298 else
20299 {
20300 set_register(sarg1, 0);
20301 }
20302 }
20303 }
20304
20305 void FFScript::do_paldata_clearcolor()
20306 {
20307 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
20308 {
20309 int32_t ind = get_register(sarg1) / 10000;
20310 if (unsigned(ind) >= PALDATA_NUM_COLORS)
20311 {
20312 Z_scripterrlog("Invalid color index (%d) passed to paldata->ClearColor(). Valid indices are 0-255. Aborting.\n", ind);
20313 return;
20314 }
20315 set_bit(pd->colors_used, ind, false);
20316 }
20317 }
20318
20319 void FFScript::do_paldata_clearcset()
20320 {
20321 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
20322 {
20323 int32_t cs = get_register(sarg1) / 10000;
20324 if (unsigned(cs) > 15)
20325 {
20326 Z_scripterrlog("Invalid cset (%d) passed to paldata->ClearCSet(). Valid csets are 0-15. Aborting.\n", cs);
20327 return;
20328 }
20329 for (int32_t q = 0; q < 16; ++q)
20330 {
20331 set_bit(pd->colors_used, CSET(cs) + q, false);
20332 }
20333 }
20334 }
20335
20336 int32_t FFScript::do_paldata_getrgb(user_paldata* pd, int32_t index, int32_t c)
20337 {
20338 if (pd)
20339 {
20340 int32_t ind = index;
20341 if (unsigned(ind) >= PALDATA_NUM_COLORS)
20342 {
20343 scripting_log_error_with_context("Invalid color index ({}). Valid indices are 0-255.", ind);
20344 return -1;
20345 }
20346 if (!get_bit(pd->colors_used, ind))
20347 {
20348 scripting_log_error_with_context("Tried to access unused color {}.", ind);
20349 return -1;
20350 }
20351 switch (c)
20352 {
20353 case 0:
20354 return pd->colors[ind].r;
20355 case 1:
20356 return pd->colors[ind].g;
20357 case 2:
20358 return pd->colors[ind].b;
20359 }
20360 }
20361
20362 return -1;
20363 }
20364
20365 void FFScript::do_paldata_setrgb(user_paldata* pd, int32_t index, int32_t val, int32_t c)
20366 {
20367 if (pd)
20368 {
20369 int32_t ind = index;
20370 if (unsigned(ind) >= PALDATA_NUM_COLORS)
20371 {
20372 scripting_log_error_with_context("Invalid color index ({}). Valid indices are 0-255. Aborting.", ind);
20373 return;
20374 }
20375 if (unsigned(val) > scripting_max_color_val)
20376 {
20377 scripting_log_error_with_context("RGB value({}) is out of range. RGB values range from 0 - {}.", val, scripting_max_color_val);
20378 val = vbound(val, 0, scripting_max_color_val);
20379 }
20380 if (!get_bit(pd->colors_used, ind))
20381 {
20382 scripting_log_error_with_context("Tried to access unused color {}.", ind);
20383 return;
20384 }
20385 switch (c)
20386 {
20387 case 0:
20388 pd->colors[ind].r = val;
20389 break;
20390 case 1:
20391 pd->colors[ind].g = val;
20392 break;
20393 case 2:
20394 pd->colors[ind].b = val;
20395 break;
20396 }
20397 }
20398 }
20399
20400 450 void FFScript::do_paldata_mix()
20401 {
20402 450 int32_t ref = SH::read_stack(ri->sp + 4);
20403
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 450 times.
450 if (user_paldata* pd = checkPalData(ref))
20404 {
20405 450 int32_t ref1 = SH::read_stack(ri->sp + 3);
20406 450 int32_t ref2 = SH::read_stack(ri->sp + 2);
20407 450 double percent = SH::read_stack(ri->sp + 1)/10000.0;
20408 450 int32_t color_space = SH::read_stack(ri->sp + 0)/10000;
20409
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 450 times.
450 if (user_paldata* pd_start = checkPalData(ref1))
20410 {
20411
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 450 times.
450 if (user_paldata* pd_end = checkPalData(ref2))
20412 {
20413 450 pd->mix(pd_start, pd_end, percent, color_space);
20414 450 }
20415 450 }
20416 450 }
20417 450 }
20418
20419 4781 void FFScript::do_paldata_mixcset()
20420 {
20421 4781 int32_t ref = SH::read_stack(ri->sp + 5);
20422
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4781 times.
4781 if (user_paldata* pd = checkPalData(ref))
20423 {
20424 4781 int32_t ref1 = SH::read_stack(ri->sp + 4);
20425 4781 int32_t ref2 = SH::read_stack(ri->sp + 3);
20426 4781 int32_t cset = SH::read_stack(ri->sp + 2) / 10000;
20427 4781 double percent = SH::read_stack(ri->sp + 1) / 10000.0;
20428 4781 int32_t color_space = SH::read_stack(ri->sp + 0) / 10000;
20429
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4781 times.
4781 if (user_paldata* pd_start = checkPalData(ref1))
20430 {
20431
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4781 times.
4781 if (user_paldata* pd_end = checkPalData(ref2))
20432 {
20433
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4781 times.
4781 if (unsigned(cset) > 15)
20434 {
20435 Z_scripterrlog("CSet passed to 'paldata->MixCSet()' out of range. Valid CSets are 0-15\n");
20436 return;
20437 }
20438 4781 pd->mix(pd_start, pd_end, percent, color_space, CSET(cset), CSET(cset) + 16);
20439 4781 }
20440 4781 }
20441 4781 }
20442 4781 }
20443
20444 void FFScript::do_paldata_copy()
20445 {
20446 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
20447 {
20448 int32_t ref_dest = get_register(sarg1);
20449 if (user_paldata* pd_dest = checkPalData(ref_dest))
20450 {
20451 for (int32_t q = 0; q < PALDATA_NUM_COLORS; ++q)
20452 {
20453 pd_dest->colors[q] = pd->colors[q];
20454 }
20455 for (int32_t q = 0; q < PALDATA_BITSTREAM_SIZE; ++q)
20456 {
20457 pd_dest->colors_used[q] = pd->colors_used[q];
20458 }
20459 }
20460 }
20461 }
20462
20463 112 void FFScript::do_paldata_copycset()
20464 {
20465 112 ri->paldataref = SH::read_stack(ri->sp + 3);
20466
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
112 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
20467 {
20468 112 int32_t ref_dest = SH::read_stack(ri->sp + 2);
20469 112 int32_t cs = SH::read_stack(ri->sp + 1) / 10000;
20470 112 int32_t cs_dest = SH::read_stack(ri->sp + 0) / 10000;
20471
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
112 if (user_paldata* pd_dest = checkPalData(ref_dest))
20472 {
20473
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
112 if (unsigned(cs) > 15)
20474 {
20475 Z_scripterrlog("Invalid CSet (%d) passed to paldata->CopyCSet(). Valid CSets are 0-15. Aborting.\n", cs);
20476 return;
20477 }
20478
2/2
✓ Branch 0 taken 1792 times.
✓ Branch 1 taken 112 times.
1904 for (int32_t q = 0; q < 16; ++q)
20479 {
20480 1792 pd_dest->colors[CSET(cs_dest) + q] = pd->colors[CSET(cs) + q];
20481 1792 set_bit(pd_dest->colors_used, CSET(cs_dest) + q, bool(get_bit(pd->colors_used, CSET(cs) + q)));
20482 1792 }
20483 112 }
20484 112 }
20485 112 }
20486
20487 //Loads a cset to paldata from memory
20488 1497 void user_paldata::load_cset(int32_t cset, int32_t dataset)
20489 {
20490 1497 byte* si = colordata + CSET(dataset) * 3;
20491
2/2
✓ Branch 0 taken 23952 times.
✓ Branch 1 taken 1497 times.
25449 for (int32_t q = 0; q < 16; ++q)
20492 {
20493 23952 int32_t ind = CSET(cset) + q;
20494 23952 colors[ind].r = scripting_read_pal_color(si[0]);
20495 23952 colors[ind].g = scripting_read_pal_color(si[1]);
20496 23952 colors[ind].b = scripting_read_pal_color(si[2]);
20497 23952 set_bit(colors_used, ind, true);
20498 23952 si += 3;
20499 23952 }
20500 1497 }
20501
20502 //Loads a cset to paldata from the main palette
20503 1472 void user_paldata::load_cset_main(int32_t cset)
20504 {
20505
2/2
✓ Branch 0 taken 23552 times.
✓ Branch 1 taken 1472 times.
25024 for (int32_t q = 0; q < 16; ++q)
20506 {
20507 23552 int32_t ind = CSET(cset) + q;
20508 23552 colors[ind].r = scripting_read_pal_color(RAMpal[ind].r);
20509 23552 colors[ind].g = scripting_read_pal_color(RAMpal[ind].g);
20510 23552 colors[ind].b = scripting_read_pal_color(RAMpal[ind].b);
20511 23552 set_bit(colors_used, ind, true);
20512 23552 }
20513 1472 }
20514
20515 //Writes to a memory cset from paldata
20516 2905 void user_paldata::write_cset(int32_t cset, int32_t dataset)
20517 {
20518 2905 byte* si = colordata + CSET(dataset) * 3;
20519
2/2
✓ Branch 0 taken 46480 times.
✓ Branch 1 taken 2905 times.
49385 for (int32_t q = 0; q < 16; ++q)
20520 {
20521 46480 int32_t ind = CSET(cset) + q;
20522
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46480 times.
46480 if (get_bit(colors_used, ind))
20523 {
20524 46480 si[0] = scripting_write_pal_color(colors[ind].r);
20525 46480 si[1] = scripting_write_pal_color(colors[ind].g);
20526 46480 si[2] = scripting_write_pal_color(colors[ind].b);
20527 46480 }
20528 46480 si += 3;
20529 46480 }
20530 2905 }
20531
20532 //Writes to a main palette cset from paldata
20533 5791 void user_paldata::write_cset_main(int32_t cset)
20534 {
20535
2/2
✓ Branch 0 taken 92656 times.
✓ Branch 1 taken 5791 times.
98447 for (int32_t q = 0; q < 16; ++q)
20536 {
20537 92656 int32_t ind = CSET(cset) + q;
20538
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 92656 times.
92656 if (get_bit(colors_used, ind))
20539 {
20540 92656 RAMpal[ind] = colors[ind];
20541
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 92656 times.
92656 if (!scripting_use_8bit_colors)
20542 92656 convertRGB(RAMpal[ind]);
20543 92656 }
20544 92656 }
20545 5791 }
20546
20547
20548 //Checks a memory cset from
20549
20550
20551
20552
20553 3425 bool user_paldata::check_cset(int32_t cset, int32_t dataset)
20554 {
20555 3425 byte* si = colordata + CSET(dataset) * 3;
20556
2/2
✓ Branch 0 taken 11375 times.
✓ Branch 1 taken 520 times.
11895 for (int32_t q = 0; q < 16; ++q)
20557 {
20558 11375 int32_t ind = CSET(cset) + q;
20559
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11375 times.
11375 if (get_bit(colors_used, ind))
20560 {
20561
2/2
✓ Branch 0 taken 9482 times.
✓ Branch 1 taken 1893 times.
11375 if (scripting_read_pal_color(si[0]) != colors[ind].r)
20562 1893 return true;
20563
2/2
✓ Branch 0 taken 8470 times.
✓ Branch 1 taken 1012 times.
9482 if (scripting_read_pal_color(si[1]) != colors[ind].g)
20564 1012 return true;
20565
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8470 times.
8470 if (scripting_read_pal_color(si[2]) != colors[ind].b)
20566 return true;
20567 8470 }
20568 8470 si += 3;
20569 8470 }
20570 520 return false;
20571 3425 }
20572
20573 //Checks a memory cset from the main palette
20574 17154 bool user_paldata::check_cset_main(int32_t cset)
20575 {
20576
2/2
✓ Branch 0 taken 188844 times.
✓ Branch 1 taken 11363 times.
200207 for (int32_t q = 0; q < 16; ++q)
20577 {
20578 188844 int32_t ind = CSET(cset) + q;
20579
2/2
✓ Branch 0 taken 96064 times.
✓ Branch 1 taken 92780 times.
188844 if (get_bit(colors_used, ind))
20580 {
20581
2/2
✓ Branch 0 taken 88937 times.
✓ Branch 1 taken 3843 times.
92780 if (scripting_read_pal_color(RAMpal[ind].r) != colors[ind].r)
20582 3843 return true;
20583
2/2
✓ Branch 0 taken 87200 times.
✓ Branch 1 taken 1737 times.
88937 if (scripting_read_pal_color(RAMpal[ind].g) != colors[ind].g)
20584 1737 return true;
20585
2/2
✓ Branch 0 taken 211 times.
✓ Branch 1 taken 86989 times.
87200 if (scripting_read_pal_color(RAMpal[ind].b) != colors[ind].b)
20586 211 return true;
20587 86989 }
20588 183053 }
20589 11363 return false;
20590 17154 }
20591
20592 //Mixes a color between two paldatas
20593 139696 RGB user_paldata::mix_color(RGB start, RGB end, double percent, int32_t color_space)
20594 {
20595 139696 double upper = scripting_max_color_val;
20596 139696 int32_t direction = 0;
20597
1/13
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 139696 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
139696 switch (color_space)
20598 {
20599 case CSPACE_RGB:
20600 279392 return _RGB(byte(vbound(double(zc::math::Lerp(start.r, end.r, percent)), 0.0, upper)),
20601 139696 byte(vbound(double(zc::math::Lerp(start.g, end.g, percent)), 0.0, upper)),
20602 139696 byte(vbound(double(zc::math::Lerp(start.b, end.b, percent)), 0.0, upper)));
20603 case CSPACE_CMYK:
20604 {
20605 double convert_start[4];
20606 double convert_end[4];
20607 double convert_result[4];
20608 RGBTo(start, convert_start, color_space);
20609 RGBTo(end, convert_end, color_space);
20610 convert_result[0] = zc::math::Lerp(convert_start[0], convert_end[0], percent);
20611 convert_result[1] = zc::math::Lerp(convert_start[1], convert_end[1], percent);
20612 convert_result[2] = zc::math::Lerp(convert_start[2], convert_end[2], percent);
20613 convert_result[3] = zc::math::Lerp(convert_start[3], convert_end[3], percent);
20614 return RGBFrom(convert_result, color_space);
20615 }
20616 case CSPACE_HSV_CW:
20617 if (color_space == CSPACE_HSV_CW)
20618 direction = 1;
20619 [[fallthrough]];
20620 case CSPACE_HSV_CCW:
20621 if (color_space == CSPACE_HSV_CCW)
20622 direction = -1;
20623 [[fallthrough]];
20624 case CSPACE_HSV:
20625 {
20626 double convert_start[3];
20627 double convert_end[3];
20628 double convert_result[3];
20629 RGBTo(start, convert_start, color_space);
20630 RGBTo(end, convert_end, color_space);
20631 convert_result[0] = WrapLerp(convert_start[0], convert_end[0], percent, 0.0, 1.0, direction);
20632 convert_result[1] = zc::math::Lerp(convert_start[1], convert_end[1], percent);
20633 convert_result[2] = zc::math::Lerp(convert_start[2], convert_end[2], percent);
20634 return RGBFrom(convert_result, color_space);
20635 }
20636 case CSPACE_HSL_CW:
20637 if (color_space == CSPACE_HSL_CW)
20638 direction = 1;
20639 [[fallthrough]];
20640 case CSPACE_HSL_CCW:
20641 if (color_space == CSPACE_HSL_CCW)
20642 direction = -1;
20643 [[fallthrough]];
20644 case CSPACE_HSL:
20645 {
20646 double convert_start[3];
20647 double convert_end[3];
20648 double convert_result[3];
20649 RGBTo(start, convert_start, color_space);
20650 RGBTo(end, convert_end, color_space);
20651 convert_result[0] = WrapLerp(convert_start[0], convert_end[0], percent, 0.0, 1.0, direction);
20652 convert_result[1] = zc::math::Lerp(convert_start[1], convert_end[1], percent);
20653 convert_result[2] = zc::math::Lerp(convert_start[2], convert_end[2], percent);
20654 return RGBFrom(convert_result, color_space);
20655 }
20656 case CSPACE_LAB:
20657 {
20658 double convert_start[3];
20659 double convert_end[3];
20660 double convert_result[3];
20661 RGBTo(start, convert_start, color_space);
20662 RGBTo(end, convert_end, color_space);
20663 convert_result[0] = zc::math::Lerp(convert_start[0], convert_end[0], percent);
20664 convert_result[1] = zc::math::Lerp(convert_start[1], convert_end[1], percent);
20665 convert_result[2] = zc::math::Lerp(convert_start[2], convert_end[2], percent);
20666 return RGBFrom(convert_result, color_space);
20667 }
20668 case CSPACE_LCH_CW:
20669 if (color_space == CSPACE_LCH_CW)
20670 direction = 1;
20671 [[fallthrough]];
20672 case CSPACE_LCH_CCW:
20673 if (color_space == CSPACE_LCH_CCW)
20674 direction = -1;
20675 [[fallthrough]];
20676 case CSPACE_LCH:
20677 {
20678 double convert_start[3];
20679 double convert_end[3];
20680 double convert_result[3];
20681 RGBTo(start, convert_start, color_space);
20682 RGBTo(end, convert_end, color_space);
20683 convert_result[0] = zc::math::Lerp(convert_start[0], convert_end[0], percent);
20684 convert_result[1] = zc::math::Lerp(convert_start[1], convert_end[1], percent);
20685 convert_result[2] = WrapLerp(convert_start[2], convert_end[2], percent, 0.0, 360.0, direction);
20686 return RGBFrom(convert_result, color_space);
20687 }
20688 }
20689 return start;
20690 139696 }
20691
20692 void user_paldata::RGBTo(RGB c, double arr[], int32_t color_space)
20693 {
20694 //From easyrgb.com/en/math.php
20695 double upper = scripting_max_color_val;
20696 double r = vbound(c.r / upper, 0.0, 1.0);
20697 double g = vbound(c.g / upper, 0.0, 1.0);
20698 double b = vbound(c.b / upper, 0.0, 1.0);
20699 switch (color_space)
20700 {
20701 case CSPACE_CMYK:
20702 {
20703 double c = 1.0 - r;
20704 double m = 1.0 - g;
20705 double y = 1.0 - b;
20706
20707 double k = 1.0;
20708
20709 if (c < k) k = c;
20710 if (m < k) k = m;
20711 if (y < k) k = y;
20712 if (k == 1)
20713 {
20714 c = 0.0;
20715 m = 0.0;
20716 y = 0.0;
20717 }
20718 else
20719 {
20720 c = (c - k) / (1.0 - k);
20721 m = (m - k) / (1.0 - k);
20722 y = (y - k) / (1.0 - k);
20723 }
20724 arr[0] = c;
20725 arr[1] = m;
20726 arr[2] = y;
20727 arr[3] = k;
20728 break;
20729 }
20730 case CSPACE_HSV_CW:
20731 case CSPACE_HSV_CCW:
20732 case CSPACE_HSV:
20733 {
20734 double min_val = std::min(std::min(r, g), b);
20735 double max_val = std::max(std::max(r, g), b);
20736 double del_max = max_val - min_val;
20737
20738 double h = 0;
20739 double s = 0;
20740 double v = max_val;
20741
20742 if (del_max != 0) //Set chroma if not gray
20743 {
20744 s = del_max / max_val;
20745
20746 double del_r = (((max_val - r) / 6.0) + (del_max / 2.0)) / del_max;
20747 double del_g = (((max_val - g) / 6.0) + (del_max / 2.0)) / del_max;
20748 double del_b = (((max_val - b) / 6.0) + (del_max / 2.0)) / del_max;
20749
20750 if (r == max_val) h = del_b - del_g;
20751 else if (g == max_val) h = (1.0 / 3.0) + del_r - del_b;
20752 else if (b == max_val) h = (2.0 / 3.0) + del_g - del_r;
20753
20754 if (h < 0) ++h;
20755 if (h > 1) --h;
20756 }
20757
20758 arr[0] = h;
20759 arr[1] = s;
20760 arr[2] = v;
20761 break;
20762 }
20763 case CSPACE_HSL_CW:
20764 case CSPACE_HSL_CCW:
20765 case CSPACE_HSL:
20766 {
20767 double min_val = std::min(std::min(r, g), b);
20768 double max_val = std::max(std::max(r, g), b);
20769 double del_max = max_val - min_val;
20770
20771 double h = 0;
20772 double s = 0;
20773 double l = (max_val + min_val) / 2.0;
20774
20775 if (del_max != 0) //Set chroma if not gray
20776 {
20777 if (l < 0.5) s = del_max / (max_val + min_val);
20778 else s = del_max / (2 - max_val - min_val);
20779
20780 double del_r = (((max_val - r) / 6.0) + (del_max / 2.0)) / del_max;
20781 double del_g = (((max_val - g) / 6.0) + (del_max / 2.0)) / del_max;
20782 double del_b = (((max_val - b) / 6.0) + (del_max / 2.0)) / del_max;
20783
20784 if (r == max_val) h = del_b - del_g;
20785 else if (g == max_val) h = (1.0 / 3.0) + del_r - del_b;
20786 else if (b == max_val) h = (2.0 / 3.0) + del_g - del_r;
20787
20788 if (h < 0) ++h;
20789 if (h > 1) --h;
20790 }
20791
20792 arr[0] = h;
20793 arr[1] = s;
20794 arr[2] = l;
20795 break;
20796 }
20797 case CSPACE_LAB:
20798 {
20799 if (r > 0.04045) r = pow(((r + 0.055) / 1.055), 2.4);
20800 else r /= 12.92;
20801 if (g > 0.04045) g = pow(((g + 0.055) / 1.055), 2.4);
20802 else g /= 12.92;
20803 if (b > 0.04045) b = pow(((b + 0.055) / 1.055), 2.4);
20804 else b /= 12.92;
20805
20806 double x = r * 0.4124 + g * 0.3576 + b * 0.1805;
20807 double y = r * 0.2126 + g * 0.7152 + b * 0.0722;
20808 double z = r * 0.0193 + g * 0.1192 + b * 0.9505;
20809
20810 if (x > 0.008856) x = pow(x, 1.0 / 3.0);
20811 else x = (7.787 * x) + (16.0 / 116.0);
20812 if (y > 0.008856) y = pow(y, 1.0 / 3.0);
20813 else y = (7.787 * y) + (16.0 / 116.0);
20814 if (z > 0.008856) z = pow(z, 1.0 / 3.0);
20815 else z = (7.787 * z) + (16.0 / 116.0);
20816
20817 double CIEL = (116 * y) - 16;
20818 double CIEa = 500 * (x - y);
20819 double CIEb = 200 * (y - z);
20820
20821 arr[0] = CIEL;
20822 arr[1] = CIEa;
20823 arr[2] = CIEb;
20824 break;
20825 }
20826 case CSPACE_LCH_CW:
20827 case CSPACE_LCH_CCW:
20828 case CSPACE_LCH:
20829 {
20830 if (r > 0.04045) r = pow(((r + 0.055) / 1.055), 2.4);
20831 else r /= 12.92;
20832 if (g > 0.04045) g = pow(((g + 0.055) / 1.055), 2.4);
20833 else g /= 12.92;
20834 if (b > 0.04045) b = pow(((b + 0.055) / 1.055), 2.4);
20835 else b /= 12.92;
20836
20837 double x = r * 0.4124 + g * 0.3576 + b * 0.1805;
20838 double y = r * 0.2126 + g * 0.7152 + b * 0.0722;
20839 double z = r * 0.0193 + g * 0.1192 + b * 0.9505;
20840
20841 if (x > 0.008856) x = pow(x, 1.0 / 3.0);
20842 else x = (7.787 * x) + (16.0 / 116.0);
20843 if (y > 0.008856) y = pow(y, 1.0 / 3.0);
20844 else y = (7.787 * y) + (16.0 / 116.0);
20845 if (z > 0.008856) z = pow(z, 1.0 / 3.0);
20846 else z = (7.787 * z) + (16.0 / 116.0);
20847
20848 double CIEL = (116 * y) - 16;
20849 double CIEa = 500 * (x - y);
20850 double CIEb = 200 * (y - z);
20851
20852 double h = atan2(CIEb, CIEa);
20853 if (h > 0) h = (h / PI) * 180;
20854 else h = 360 - (abs(h) / PI) * 180;
20855
20856 double CIEC = sqrt(pow(CIEa, 2) + pow(CIEb, 2));
20857
20858 arr[0] = CIEL;
20859 arr[1] = CIEC;
20860 arr[2] = h;
20861 break;
20862 }
20863 }
20864
20865 }
20866
20867 RGB user_paldata::RGBFrom(double arr[], int32_t color_space)
20868 {
20869 double upper = scripting_max_color_val;
20870 double r = 0.0;
20871 double g = 0.0;
20872 double b = 0.0;
20873 switch (color_space)
20874 {
20875 case CSPACE_CMYK:
20876 {
20877 double c = (arr[0] * (1 - arr[3]) + arr[3]);
20878 double m = (arr[1] * (1 - arr[3]) + arr[3]);
20879 double y = (arr[2] * (1 - arr[3]) + arr[3]);
20880
20881 r = vbound((1 - c) * upper, 0.0, upper);
20882 g = vbound((1 - m) * upper, 0.0, upper);
20883 b = vbound((1 - y) * upper, 0.0, upper);
20884 return _RGB(r, g, b);
20885 break;
20886 }
20887 case CSPACE_HSV_CW:
20888 case CSPACE_HSV_CCW:
20889 case CSPACE_HSV:
20890 {
20891 double h = arr[0];
20892 double s = arr[1];
20893 double v = arr[2];
20894
20895 if (s == 0)
20896 {
20897 r = v;
20898 g = v;
20899 b = v;
20900 }
20901 else
20902 {
20903 double var_h = h * 6;
20904 if (var_h >= 6) var_h = 0;
20905 int32_t var_i = floor(var_h);
20906 double var_1 = v * (1 - s);
20907 double var_2 = v * (1 - s * (var_h - var_i));
20908 double var_3 = v * (1 - s * (1 - (var_h - var_i)));
20909
20910 switch (var_i)
20911 {
20912 case 0:
20913 r = v;
20914 g = var_3;
20915 b = var_1;
20916 break;
20917 case 1:
20918 r = var_2;
20919 g = v;
20920 b = var_1;
20921 break;
20922 case 2:
20923 r = var_1;
20924 g = v;
20925 b = var_3;
20926 break;
20927 case 3:
20928 r = var_1;
20929 g = var_2;
20930 b = v;
20931 break;
20932 case 4:
20933 r = var_3;
20934 g = var_1;
20935 b = v;
20936 break;
20937 default:
20938 r = v;
20939 g = var_1;
20940 b = var_2;
20941 }
20942 }
20943
20944 r = vbound(r * upper, 0.0, upper);
20945 g = vbound(g * upper, 0.0, upper);
20946 b = vbound(b * upper, 0.0, upper);
20947
20948 return _RGB(r, g, b);
20949 }
20950 case CSPACE_HSL_CW:
20951 case CSPACE_HSL_CCW:
20952 case CSPACE_HSL:
20953 {
20954 double h = arr[0];
20955 double s = arr[1];
20956 double l = arr[2];
20957
20958 if (s == 0)
20959 {
20960 r = l;
20961 g = l;
20962 b = l;
20963 }
20964 else
20965 {
20966 double var_1;
20967 double var_2;
20968 if (l < 0.5)var_2 = l * (1 + s);
20969 else var_2 = (l + s) - (s * l);
20970
20971 var_1 = 2 * l - var_2;
20972
20973 r = HueToRGB(var_1, var_2, h + (1.0 / 3.0));
20974 g = HueToRGB(var_1, var_2, h);
20975 b = HueToRGB(var_1, var_2, h - (1.0 / 3.0));
20976 }
20977
20978 r = vbound(r * upper, 0.0, upper);
20979 g = vbound(g * upper, 0.0, upper);
20980 b = vbound(b * upper, 0.0, upper);
20981
20982 return _RGB(r, g, b);
20983 }
20984 case CSPACE_LAB:
20985 {
20986 double CIEL = arr[0];
20987 double CIEa = arr[1];
20988 double CIEb = arr[2];
20989
20990 double var_y = (CIEL + 16) / 116.0;
20991 double var_x = CIEa / 500.0 + var_y;
20992 double var_z = var_y - CIEb / 200.0;
20993
20994 if (pow(var_x, 3) > 0.008856) var_x = pow(var_x, 3);
20995 else var_x = (var_x - 16.0 / 116.0) / 7.787;
20996 if (pow(var_y, 3) > 0.008856) var_y = pow(var_y, 3);
20997 else var_y = (var_y - 16.0 / 116.0) / 7.787;
20998 if (pow(var_z, 3) > 0.008856) var_z = pow(var_z, 3);
20999 else var_z = (var_z - 16.0 / 116.0) / 7.787;
21000
21001 r = var_x * 3.2406 + var_y * -1.5372 + var_z * -0.4986;
21002 g = var_x * -0.9689 + var_y * 1.8758 + var_z * 0.0415;
21003 b = var_x * 0.0557 + var_y * -0.2040 + var_z * 1.0570;
21004
21005 if (r > 0.0031308) r = 1.055 * pow(r, (1 / 2.4)) - 0.055;
21006 else r = 12.92 * r;
21007 if (g > 0.0031308) g = 1.055 * pow(g, (1 / 2.4)) - 0.055;
21008 else g = 12.92 * g;
21009 if (b > 0.0031308) b = 1.055 * pow(b, (1 / 2.4)) - 0.055;
21010 else b = 12.92 * b;
21011
21012 r = vbound(r * upper, 0.0, upper);
21013 g = vbound(g * upper, 0.0, upper);
21014 b = vbound(b * upper, 0.0, upper);
21015
21016 return _RGB(r, g, b);
21017 }
21018 case CSPACE_LCH_CW:
21019 case CSPACE_LCH_CCW:
21020 case CSPACE_LCH:
21021 {
21022 double CIEL = arr[0];
21023 double CIEa = cos((arr[2] * PI) / 180.0) * arr[1];
21024 double CIEb = sin((arr[2] * PI) / 180.0) * arr[1];
21025
21026 double var_y = (CIEL + 16) / 116.0;
21027 double var_x = CIEa / 500.0 + var_y;
21028 double var_z = var_y - CIEb / 200.0;
21029
21030 if (pow(var_y, 3) > 0.008856) var_y = pow(var_y, 3);
21031 else var_y = (var_y - 16.0 / 116.0) / 7.787;
21032 if (pow(var_x, 3) > 0.008856) var_x = pow(var_x, 3);
21033 else var_x = (var_x - 16.0 / 116.0) / 7.787;
21034 if (pow(var_z, 3) > 0.008856) var_z = pow(var_z, 3);
21035 else var_z = (var_z - 16.0 / 116.0) / 7.787;
21036
21037 r = var_x * 3.2406 + var_y * -1.5372 + var_z * -0.4986;
21038 g = var_x * -0.9689 + var_y * 1.8758 + var_z * 0.0415;
21039 b = var_x * 0.0557 + var_y * -0.2040 + var_z * 1.0570;
21040
21041 if (r > 0.0031308) r = 1.055 * pow(r, (1 / 2.4)) - 0.055;
21042 else r = 12.92 * r;
21043 if (g > 0.0031308) g = 1.055 * pow(g, (1 / 2.4)) - 0.055;
21044 else g = 12.92 * g;
21045 if (b > 0.0031308) b = 1.055 * pow(b, (1 / 2.4)) - 0.055;
21046 else b = 12.92 * b;
21047
21048 r = vbound(r * upper, 0.0, upper);
21049 g = vbound(g * upper, 0.0, upper);
21050 b = vbound(b * upper, 0.0, upper);
21051
21052 return _RGB(r, g, b);
21053 }
21054 }
21055 return _RGB(0, 0, 0);
21056 }
21057 double user_paldata::HueToRGB(double v1, double v2, double vH)
21058 {
21059 if (vH < 0) vH += 1;
21060 if (vH > 1) vH -= 1;
21061 if ((6 * vH) < 1) return (v1 + (v2 - v1) * 6 * vH);
21062 if ((2 * vH) < 1) return (v2);
21063 if ((3 * vH) < 2) return (v1 + (v2 - v1) * ((2.0 / 3.0) - vH) * 6);
21064 return (v1);
21065 }
21066
21067 double user_paldata::WrapLerp(double a, double b, double t, double min, double max, int32_t direction)
21068 {
21069 double dif = abs(a - b);
21070 double range = abs(max - min);
21071
21072 switch (direction)
21073 {
21074 case 0:
21075 if (dif > range * 0.5)
21076 dif = range - dif;
21077 if (a + dif == b)
21078 direction = 1;
21079 else
21080 direction = -1;
21081 break;
21082 case 1:
21083 if (b < a)
21084 dif = range - dif;
21085 break;
21086 case -1:
21087 if (b > a)
21088 dif = range - dif;
21089 break;
21090 }
21091
21092 double ret = zc::math::Lerp(a, a + dif * direction, t);
21093
21094 if (ret <= min)
21095 ret += range;
21096 else if (ret >= max)
21097 ret -= range;
21098 return ret;
21099 }
21100
21101 //Mixes an entire palette given two paldatas
21102 5231 void user_paldata::mix(user_paldata *pal_start, user_paldata *pal_end, double percent, int32_t color_space, int32_t start_color, int32_t end_color)
21103 {
21104
2/2
✓ Branch 0 taken 184496 times.
✓ Branch 1 taken 5231 times.
189727 for (int32_t q = start_color; q < end_color; ++q)
21105 {
21106
3/4
✓ Branch 0 taken 139696 times.
✓ Branch 1 taken 44800 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 139696 times.
184496 if (get_bit(pal_start->colors_used, q) && get_bit(pal_end->colors_used, q)) {
21107 139696 RGB start = pal_start->colors[q];
21108 139696 RGB end = pal_end->colors[q];
21109 139696 colors[q] = mix_color(start, end, percent, color_space);
21110 139696 set_bit(colors_used, q, true);
21111 139696 }
21112 184496 }
21113 5231 }
21114
21115 53 void item_display_name(const bool setter)
21116 {
21117 53 int32_t ID = GET_REF(itemdataref);
21118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53 times.
53 if(unsigned(ID) >= MAXITEMS)
21119 return;
21120 53 int32_t arrayptr = get_register(sarg1);
21121
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53 times.
53 if(setter)
21122 {
21123 std::string str;
21124 ArrayH::getString(arrayptr, str, 255);
21125 strcpy(itemsbuf[ID].display_name, str.c_str());
21126 }
21127 else
21128 {
21129
3/6
✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53 times.
✓ Branch 4 taken 53 times.
✗ Branch 5 not taken.
53 if(ArrayH::setArray(arrayptr, string(itemsbuf[ID].display_name)) == SH::_Overflow)
21130 Z_scripterrlog("Array supplied to 'itemdata->GetDisplayName()' not large enough\n");
21131 }
21132 53 }
21133 void item_shown_name()
21134 {
21135 int32_t ID = GET_REF(itemdataref);
21136 if(unsigned(ID) >= MAXITEMS)
21137 return;
21138 int32_t arrayptr = get_register(sarg1);
21139 if(ArrayH::setArray(arrayptr, itemsbuf[ID].get_name()) == SH::_Overflow)
21140 Z_scripterrlog("Array supplied to 'itemdata->GetShownName()' not large enough\n");
21141 }
21142
21143 void FFScript::do_getDMapData_dmapname(const bool v)
21144 {
21145 int32_t ID = GET_REF(dmapdataref);
21146 int32_t arrayptr = get_register(sarg1);
21147
21148 if(BC::checkDMapID(ID) != SH::_NoError)
21149 return;
21150
21151 if(ArrayH::setArray(arrayptr, string(DMaps[ID].name)) == SH::_Overflow)
21152 Z_scripterrlog("Array supplied to 'dmapdata->GetName()' not large enough\n");
21153 }
21154
21155 void FFScript::do_setDMapData_dmapname(const bool v)
21156 {
21157 int32_t ID = GET_REF(dmapdataref);
21158 int32_t arrayptr = get_register(sarg1);
21159
21160 string filename_str;
21161
21162 if(BC::checkDMapID(ID) != SH::_NoError)
21163 return;
21164
21165
21166 ArrayH::getString(arrayptr, filename_str, 22);
21167 strncpy(DMaps[ID].name, filename_str.c_str(), 21);
21168 DMaps[ID].name[20]='\0';
21169 }
21170
21171 void FFScript::do_getDMapData_dmaptitle(const bool v)
21172 {
21173 int32_t ID = GET_REF(dmapdataref);
21174 int32_t arrayptr = get_register(sarg1);
21175
21176 if(BC::checkDMapID(ID) != SH::_NoError)
21177 return;
21178
21179 if (!get_qr(qr_OLD_DMAP_INTRO_STRINGS))
21180 {
21181 ArrayManager am(arrayptr);
21182 am.resize(DMaps[ID].title.size() + 1);
21183 }
21184 if(ArrayH::setArray(arrayptr, string(DMaps[ID].title)) == SH::_Overflow)
21185 Z_scripterrlog("Array supplied to 'dmapdata->GetTitle()' not large enough\n");
21186 }
21187
21188 void FFScript::do_setDMapData_dmaptitle(const bool v)
21189 {
21190 int32_t ID = GET_REF(dmapdataref);
21191 int32_t arrayptr = get_register(sarg1);
21192 string filename_str;
21193
21194 if(BC::checkDMapID(ID) != SH::_NoError)
21195 return;
21196
21197 if (get_qr(qr_OLD_DMAP_INTRO_STRINGS))
21198 {
21199 char namestr[21];
21200 ArrayH::getString(arrayptr, filename_str, 21);
21201 strncpy(namestr, filename_str.c_str(), 20);
21202 namestr[20] = '\0';
21203 DMaps[ID].title.assign(namestr);
21204 }
21205 else
21206 {
21207 ArrayH::getString(arrayptr, filename_str, ArrayH::getSize(arrayptr));
21208 DMaps[ID].title = filename_str;
21209 }
21210 }
21211
21212 void FFScript::do_getDMapData_dmapintro(const bool v)
21213 {
21214 int32_t ID = GET_REF(dmapdataref);
21215 int32_t arrayptr = get_register(sarg1);
21216
21217 if(BC::checkDMapID(ID) != SH::_NoError)
21218 return;
21219
21220 if(ArrayH::setArray(arrayptr, string(DMaps[ID].intro)) == SH::_Overflow)
21221 Z_scripterrlog("Array supplied to 'dmapdata->GetIntro()' not large enough\n");
21222 }
21223
21224 void FFScript::do_setDMapData_dmapintro(const bool v)
21225 {
21226 int32_t ID = GET_REF(dmapdataref);
21227 int32_t arrayptr = get_register(sarg1);
21228 string filename_str;
21229
21230 if(BC::checkDMapID(ID) != SH::_NoError)
21231 return;
21232
21233
21234 ArrayH::getString(arrayptr, filename_str, 73);
21235 strncpy(DMaps[ID].intro, filename_str.c_str(), 72);
21236 DMaps[ID].intro[72]='\0';
21237 }
21238
21239 14 void FFScript::do_getDMapData_music(const bool v)
21240 {
21241 14 int32_t ID = GET_REF(dmapdataref);
21242 14 int32_t arrayptr = get_register(sarg1);
21243
21244
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if(BC::checkDMapID(ID) != SH::_NoError)
21245 return;
21246
21247
3/6
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
14 if(ArrayH::setArray(arrayptr, string(DMaps[ID].tmusic)) == SH::_Overflow)
21248 Z_scripterrlog("Array supplied to 'dmapdata->GetMusic()' not large enough\n");
21249 14 }
21250
21251 void FFScript::do_setDMapData_music(const bool v)
21252 {
21253 int32_t ID = GET_REF(dmapdataref);
21254 int32_t arrayptr = get_register(sarg1);
21255 string filename_str;
21256
21257 if(BC::checkDMapID(ID) != SH::_NoError)
21258 return;
21259
21260
21261 ArrayH::getString(arrayptr, filename_str, 56);
21262 strncpy(DMaps[ID].tmusic, filename_str.c_str(), 55);
21263 DMaps[ID].tmusic[55]='\0';
21264 }
21265
21266 6366 void FFScript::do_loadnpcdata(const bool v)
21267 {
21268 6366 int32_t ID = SH::get_arg(sarg1, v) / 10000;
21269
21270
2/4
✓ Branch 0 taken 6366 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6366 times.
6366 if ( ID < 1 || ID > (MAXGUYS-1) )
21271 {
21272 Z_scripterrlog("Invalid NPC ID passed to Game->LoadNPCData: %d\n", ID);
21273 ri->npcdataref = MAX_DWORD;
21274 }
21275
21276 6366 else ri->npcdataref = ID;
21277 6366 }
21278 54 void FFScript::do_loadmessagedata(const bool v)
21279 {
21280 54 int32_t ID = SH::get_arg(sarg1, v) / 10000;
21281
21282
2/4
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 54 times.
54 if ( ID < 1 || ID > (msg_count-1) )
21283 {
21284 Z_scripterrlog("Invalid Message ID passed to Game->LoadMessageData: %d\n", ID);
21285 ri->msgdataref = MAX_DWORD;
21286 }
21287
21288 54 else ri->msgdataref = ID;
21289 54 }
21290 //same syntax as loadmessage data
21291 //the input is an array
21292 52 void FFScript::do_messagedata_setstring(const bool v)
21293 {
21294 52 int32_t arrayptr = get_register(sarg1);
21295 52 int32_t ID = GET_REF(msgdataref);
21296
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
52 if(BC::checkMessage(ID) != SH::_NoError)
21297 return;
21298
21299 52 std::string s;
21300
1/2
✓ Branch 0 taken 52 times.
✗ Branch 1 not taken.
52 ArrayH::getString(arrayptr, s, MSG_NEW_SIZE);
21301
21302 52 auto encoding_type = get_qr(qr_OLD_SCRIPTS_MESSAGE_DATA_BINARY_ENCODING) ?
21303 MsgStr::EncodingType::Binary :
21304 MsgStr::EncodingType::Ascii;
21305
2/4
✓ Branch 0 taken 52 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
52 MsgStrings[ID].set(s, encoding_type);
21306 52 }
21307 18 void FFScript::do_messagedata_getstring(const bool v)
21308 {
21309 18 int32_t ID = GET_REF(msgdataref);
21310 18 int32_t arrayptr = get_register(sarg1);
21311
21312
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if(BC::checkMessage(ID) != SH::_NoError)
21313 return;
21314
21315
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 4 times.
18 if (get_qr(qr_OLD_SCRIPTS_MESSAGE_DATA_BINARY_ENCODING))
21316 14 MsgStrings[ID].ensureLegacyEncoding();
21317 else
21318 4 MsgStrings[ID].ensureAsciiEncoding();
21319
21320
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if(ArrayH::setArray(arrayptr, MsgStrings[ID].s, true) == SH::_Overflow)
21321 Z_scripterrlog("Array supplied to 'messagedata->Get()' not large enough\n");
21322 18 }
21323
21324 6042586 void FFScript::do_loadcombodata(const bool v)
21325 {
21326 6042586 int32_t ID = SH::get_arg(sarg1, v) / 10000;
21327
21328
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6042586 times.
6042586 if ( (unsigned)ID > (MAXCOMBOS-1) )
21329 {
21330 scripting_log_error_with_context("Invalid combodata ID: {}", GET_REF(combodataref));
21331 ri->combodataref = 0;
21332 }
21333
21334 6042586 else ri->combodataref = ID;
21335 6042586 }
21336
21337 3585254 void FFScript::do_loadmapdata_tempscr(const bool v)
21338 {
21339 3585254 int32_t layer = SH::get_arg(sarg1, v) / 10000;
21340
21341
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3585254 times.
3585254 if (BC::checkBounds(layer, 0, 6) != SH::_NoError)
21342 {
21343 ri->mapdataref = 0;
21344 set_register(sarg1, ri->mapdataref);
21345 return;
21346 }
21347
21348 3585254 ri->mapdataref = create_mapdata_temp_ref(mapdata_type::TemporaryCurrentRegion, cur_screen, layer);
21349 3585254 set_register(sarg1, ri->mapdataref);
21350 3585254 }
21351
21352 void FFScript::do_loadmapdata_tempscr2(const bool v)
21353 {
21354 int32_t layer = SH::get_arg(sarg1, v) / 10000;
21355 int32_t screen = SH::get_arg(sarg2, v) / 10000;
21356
21357 if (BC::checkBounds(layer, 0, 6) != SH::_NoError)
21358 {
21359 ri->mapdataref = 0;
21360 set_register(sarg1, ri->mapdataref);
21361 return;
21362 }
21363
21364 if (!is_in_current_region(screen))
21365 {
21366 scripting_log_error_with_context("Must use a screen in the current region. got: {}", screen);
21367 ri->mapdataref = 0;
21368 set_register(sarg1, ri->mapdataref);
21369 return;
21370 }
21371
21372 ri->mapdataref = create_mapdata_temp_ref(mapdata_type::TemporaryCurrentScreen, screen, layer);
21373 set_register(sarg1, ri->mapdataref);
21374 }
21375
21376 static void do_loadtmpscrforcombopos(const bool v)
21377 {
21378 int32_t layer = SH::get_arg(sarg1, v) / 10000;
21379 rpos_t rpos = (rpos_t)(SH::get_arg(sarg2, v) / 10000);
21380
21381 if (BC::checkBoundsRpos(rpos, (rpos_t)0, region_max_rpos) != SH::_NoError)
21382 {
21383 ri->mapdataref = 0;
21384 set_register(sarg1, ri->mapdataref);
21385 return;
21386 }
21387 if (BC::checkBounds(layer, 0, 6) != SH::_NoError)
21388 {
21389 ri->mapdataref = 0;
21390 set_register(sarg1, ri->mapdataref);
21391 return;
21392 }
21393
21394 set_register(sarg1, create_mapdata_temp_ref(mapdata_type::TemporaryCurrentScreen, get_screen_for_rpos(rpos), layer));
21395 }
21396
21397 182518 void FFScript::do_loadmapdata_scrollscr(const bool v)
21398 {
21399 182518 int32_t layer = SH::get_arg(sarg1, v) / 10000;
21400
21401
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 182518 times.
182518 if (BC::checkBounds(layer, 0, 6) != SH::_NoError)
21402 {
21403 ri->mapdataref = 0;
21404 set_register(sarg1, ri->mapdataref);
21405 return;
21406 }
21407
21408 182518 ri->mapdataref = create_mapdata_temp_ref(mapdata_type::TemporaryScrollingRegion, scrolling_hero_screen, layer);
21409 182518 set_register(sarg1, ri->mapdataref);
21410 182518 }
21411
21412 void FFScript::do_loadmapdata_scrollscr2(const bool v)
21413 {
21414 int32_t layer = SH::get_arg(sarg1, v) / 10000;
21415 int32_t screen = SH::get_arg(sarg2, v) / 10000;
21416
21417 if (BC::checkBounds(layer, 0, 6) != SH::_NoError)
21418 {
21419 ri->mapdataref = 0;
21420 set_register(sarg1, ri->mapdataref);
21421 return;
21422 }
21423
21424 if (!is_in_screenscrolling_region(screen))
21425 {
21426 scripting_log_error_with_context("Must use a screen in the current scrolling region. got: {}", screen);
21427 ri->mapdataref = 0;
21428 set_register(sarg1, ri->mapdataref);
21429 return;
21430 }
21431
21432 ri->mapdataref = create_mapdata_temp_ref(mapdata_type::TemporaryScrollingScreen, screen, layer);
21433 set_register(sarg1, ri->mapdataref);
21434 }
21435
21436 void FFScript::do_loadshopdata(const bool v)
21437 {
21438 int32_t ID = SH::get_arg(sarg1, v) / 10000;
21439
21440 if ( (unsigned)ID > 255 )
21441 {
21442 Z_scripterrlog("Invalid Shop ID passed to Game->LoadShopData: %d\n", ID);
21443 ri->shopdataref = 0;
21444 }
21445 else ri->shopdataref = ID;
21446 }
21447
21448
21449 void FFScript::do_loadinfoshopdata(const bool v)
21450 {
21451 int32_t ID = SH::get_arg(sarg1, v) / 10000;
21452
21453 if ( (unsigned)ID > 255 )
21454 {
21455 Z_scripterrlog("Invalid Shop ID passed to Game->LoadShopData: %d\n", ID);
21456 ri->shopdataref = 0;
21457 }
21458 else ri->shopdataref = ID+NUMSHOPS;
21459 }
21460
21461 5603 void FFScript::do_loadspritedata(const bool v)
21462 {
21463 5603 int32_t ID = SH::get_arg(sarg1, v) / 10000;
21464
21465
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5603 times.
5603 if ( (unsigned)ID > (MAXWPNS-1) )
21466 {
21467 Z_scripterrlog("Invalid Sprite ID passed to Game->LoadSpriteData: %d\n", ID);
21468 ri->spritedataref = 0;
21469 }
21470
21471 5603 else ri->spritedataref = ID;
21472 5603 }
21473
21474 10 void FFScript::do_loadbitmapid(const bool v)
21475 {
21476 10 int32_t ID = SH::get_arg(sarg1, v) / 10000;
21477
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 switch(ID)
21478 {
21479 case rtSCREEN:
21480 case rtBMP0:
21481 case rtBMP1:
21482 case rtBMP2:
21483 case rtBMP3:
21484 case rtBMP4:
21485 case rtBMP5:
21486 case rtBMP6:
21487 10 ri->bitmapref = ID+10; break;
21488 default:
21489 {
21490 Z_scripterrlog("Invalid Bitmap ID passed to Game->Load BitmapID: %d\n", ID);
21491 ri->bitmapref = 0; break;
21492 }
21493 }
21494 10 }
21495
21496 166704 void do_createlweapon(const bool v)
21497 {
21498 166704 const int32_t ID = SH::get_arg(sarg1, v) / 10000;
21499
21500
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 166704 times.
166704 if(BC::checkWeaponID(ID) != SH::_NoError)
21501 return;
21502
21503
1/2
✓ Branch 0 taken 166704 times.
✗ Branch 1 not taken.
166704 if ( Lwpns.has_space() )
21504 {
21505 166704 (void)Lwpns.add
21506 (
21507
1/2
✓ Branch 0 taken 166704 times.
✗ Branch 1 not taken.
333408 new weapon
21508 (
21509
1/2
✓ Branch 0 taken 166704 times.
✗ Branch 1 not taken.
166704 (zfix)0, /*X*/
21510
1/2
✓ Branch 0 taken 166704 times.
✗ Branch 1 not taken.
166704 (zfix)0, /*Y*/
21511
1/2
✓ Branch 0 taken 166704 times.
✗ Branch 1 not taken.
166704 (zfix)0, /*Z*/
21512 166704 ID, /*id*/
21513 0, /*type*/
21514 0, /*power*/
21515 0, /*dir*/
21516 -1, /*Parentid*/
21517
1/2
✓ Branch 0 taken 166704 times.
✗ Branch 1 not taken.
166704 Hero.getUID(), /*prntid*/
21518 false, /*isdummy*/
21519 1, /*script_gen*/
21520 1, /*islwpn*/
21521 166704 (ID==wWind?1:0) /*special*/
21522 )
21523 );
21524 166704 ri->lwpnref = Lwpns.spr(Lwpns.Count() - 1)->getUID();
21525 166704 weapon *w = (weapon*)Lwpns.spr(Lwpns.Count()-1); //last created
21526 166704 w->screen_spawned = ri->screenref;
21527 166704 w->ScriptGenerated = 1;
21528 166704 w->isLWeapon = 1;
21529
1/2
✓ Branch 0 taken 166704 times.
✗ Branch 1 not taken.
166704 if(ID == wWind) w->specialinfo = 1;
21530 166704 Z_eventlog("Script created lweapon %d with UID = %u\n", ID, ri->lwpnref);
21531 166704 }
21532 else
21533 {
21534 ri->lwpnref = 0; // Now NULL
21535 Z_scripterrlog("Couldn't create lweapon %d, screen lweapon limit reached\n", ID);
21536 }
21537 166704 }
21538
21539 303017 void do_createeweapon(const bool v)
21540 {
21541 303017 const int32_t ID = SH::get_arg(sarg1, v) / 10000;
21542
21543
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 303017 times.
303017 if(BC::checkWeaponID(ID) != SH::_NoError)
21544 return;
21545
21546
1/2
✓ Branch 0 taken 303017 times.
✗ Branch 1 not taken.
303017 if ( Ewpns.has_space() )
21547 {
21548 303017 addEwpn(0, 0, 0, ID, 0, 0, 0, -1,1); //Param 9 marks it as script-generated.
21549
4/6
✓ Branch 0 taken 242350 times.
✓ Branch 1 taken 60667 times.
✓ Branch 2 taken 242350 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 242350 times.
✗ Branch 5 not taken.
303017 if( ID > wEnemyWeapons || ( ID >= wScript1 && ID <= wScript10) )
21550 {
21551 303017 weapon *w = (weapon*)Ewpns.spr(Ewpns.Count()-1); //last created
21552 303017 w->screen_spawned = ri->screenref;
21553 303017 w->ScriptGenerated = 1;
21554 303017 w->isLWeapon = 0;
21555 303017 ri->ewpnref = Ewpns.spr(Ewpns.Count() - 1)->getUID();
21556 303017 Z_eventlog("Script created eweapon %d with UID = %u\n", ID, ri->ewpnref);
21557 303017 }
21558 else
21559 {
21560 Z_scripterrlog("Couldn't create eweapon: Invalid ID/Type (%d) specified.\n", ID);
21561 return;
21562 }
21563 303017 }
21564 else
21565 {
21566 ri->ewpnref = 0;
21567 Z_scripterrlog("Couldn't create eweapon %d, screen eweapon limit reached\n", ID);
21568 }
21569 303017 }
21570
21571 22558 void do_createitem(const bool v)
21572 {
21573 22558 const int32_t ID = SH::get_arg(sarg1, v) / 10000;
21574
21575
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22558 times.
22558 if(BC::checkItemID(ID) != SH::_NoError)
21576 return;
21577
21578
1/2
✓ Branch 0 taken 22558 times.
✗ Branch 1 not taken.
22558 if ( items.has_space() )
21579 {
21580 22558 additem(0, (get_qr(qr_NOITEMOFFSET) ? 1: 0), ID, ipBIGRANGE);
21581 22558 sprite* item = items.spr(items.Count() - 1);
21582 22558 item->screen_spawned = ri->screenref;
21583 22558 ri->itemref = item->getUID();
21584 22558 Z_eventlog("Script created item \"%s\" with UID = %u\n", item_string[ID], ri->itemref);
21585 22558 }
21586 else
21587 {
21588 ri->itemref = 0;
21589 Z_scripterrlog("Couldn't create item \"%s\", screen item limit reached\n", item_string[ID]);
21590 }
21591 22558 }
21592
21593 3595 void do_createnpc(const bool v)
21594 {
21595 3595 const int32_t ID = SH::get_arg(sarg1, v) / 10000;
21596
21597
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3595 times.
3595 if(BC::checkGuyID(ID) != SH::_NoError)
21598 return;
21599
21600 //If we make a segmented enemy there'll be more than one sprite created
21601 3595 word numcreated = addenemy(ri->screenref, 0, 0, ID, -10);
21602
21603
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3595 times.
3595 if(numcreated == 0)
21604 {
21605 ri->npcref = 0;
21606 Z_scripterrlog("Couldn't create NPC \"%s\", screen NPC limit reached\n", guy_string[ID]);
21607 }
21608 else
21609 {
21610 3595 word index = guys.Count() - numcreated; //Get the main enemy, not a segment
21611 3595 ri->npcref = guys.spr(index)->getUID();
21612
21613
2/2
✓ Branch 0 taken 3631 times.
✓ Branch 1 taken 3595 times.
7226 for(; index<guys.Count(); index++)
21614 3631 ((enemy*)guys.spr(index))->script_spawned=true;
21615
21616 3595 Z_eventlog("Script created NPC \"%s\" with UID = %u\n", guy_string[ID], ri->npcref);
21617 }
21618 3595 }
21619
21620 ///----------------------------------------------------------------------------------------------------//
21621 //Drawing & Sound
21622
21623 1351 void do_message(const bool v)
21624 {
21625 1351 const int32_t ID = SH::get_arg(sarg1, v) / 10000;
21626
21627
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1351 times.
1351 if(BC::checkMessage(ID) != SH::_NoError)
21628 return;
21629
21630
2/2
✓ Branch 0 taken 302 times.
✓ Branch 1 taken 1049 times.
1351 if(ID == 0)
21631 {
21632 302 dismissmsg();
21633 302 msgfont = get_zc_font(font_zfont);
21634 302 blockpath = false;
21635 302 Hero.finishedmsg();
21636 302 }
21637 else
21638 1049 donewmsg(get_scr(GET_REF(screenref)), ID);
21639 1351 }
21640
21641 53481822 INLINE void set_drawing_command_args(const int32_t j, const word numargs)
21642 {
21643
1/2
✓ Branch 0 taken 53481822 times.
✗ Branch 1 not taken.
53481822 assert(numargs <= DRAWCMD_MAX_ARG_COUNT);
21644
2/2
✓ Branch 0 taken 428972008 times.
✓ Branch 1 taken 53481822 times.
482453830 for(int32_t k = 1; k <= numargs; k++)
21645 428972008 script_drawing_commands[j][k] = SH::read_stack(ri->sp + (numargs - k));
21646 53481822 }
21647
21648 65196620 INLINE void set_user_bitmap_command_args(const int32_t j, const word numargs)
21649 {
21650
1/2
✓ Branch 0 taken 65196620 times.
✗ Branch 1 not taken.
65196620 assert(numargs <= DRAWCMD_MAX_ARG_COUNT);
21651 //ri->bitmapref = SH::read_stack(ri->sp+numargs);
21652
2/2
✓ Branch 0 taken 403729369 times.
✓ Branch 1 taken 65196620 times.
468925989 for(int32_t k = 1; k <= numargs; k++)
21653 403729369 script_drawing_commands[j][k] = SH::read_stack(ri->sp + (numargs - k));
21654 65196620 }
21655
21656 108886790 static DrawOrigin get_draw_origin_for_screen_draw_command()
21657 {
21658 108886790 DrawOrigin draw_origin = ri->screen_draw_origin;
21659
21660
2/2
✓ Branch 0 taken 3074170 times.
✓ Branch 1 taken 105812620 times.
108886790 if (draw_origin == DrawOrigin::Default)
21661 {
21662
4/4
✓ Branch 0 taken 8256 times.
✓ Branch 1 taken 105804364 times.
✓ Branch 2 taken 100787434 times.
✓ Branch 3 taken 5016930 times.
105812620 bool in_scrolling_region = is_in_scrolling_region() || (screenscrolling && scrolling_region.screen_count > 1);
21663 105812620 draw_origin = in_scrolling_region ? DrawOrigin::Region : DrawOrigin::PlayingField;
21664 105812620 }
21665
2/2
✓ Branch 0 taken 46076 times.
✓ Branch 1 taken 108840714 times.
108886790 if (draw_origin == DrawOrigin::Region)
21666 {
21667
2/2
✓ Branch 0 taken 38992 times.
✓ Branch 1 taken 7084 times.
46076 if (scrolling_using_new_region_coords)
21668 7084 draw_origin = DrawOrigin::RegionScrollingNew;
21669 46076 }
21670
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 108839230 times.
108840714 else if (draw_origin == DrawOrigin::RegionScrollingOld)
21671 {
21672 1484 draw_origin = DrawOrigin::Region;
21673 1484 }
21674
2/2
✓ Branch 0 taken 108838242 times.
✓ Branch 1 taken 988 times.
108839230 else if (draw_origin == DrawOrigin::RegionScrollingNew)
21675 {
21676
1/2
✓ Branch 0 taken 988 times.
✗ Branch 1 not taken.
988 if (!screenscrolling)
21677 draw_origin = DrawOrigin::Region;
21678 988 }
21679
21680 108886790 return draw_origin;
21681 }
21682
21683 11401698 static DrawOrigin get_draw_origin_for_bitmap_draw_command()
21684 {
21685 11401698 return DrawOrigin::Screen;
21686 }
21687
21688 120288488 static std::pair<DrawOrigin, int> get_draw_origin_for_draw_command(bool is_screen_draw, int scripting_bitmap_id)
21689 {
21690
2/2
✓ Branch 0 taken 99185808 times.
✓ Branch 1 taken 21102680 times.
120288488 if (get_qr(qr_BROKEN_SCRIPTS_BITMAP_DRAW_ORIGIN))
21691 99185808 return {get_draw_origin_for_screen_draw_command(), ri->screen_draw_origin_target};
21692
21693 21102680 auto [bitmap_id, _] = resolveScriptingBitmapId(scripting_bitmap_id);
21694
21695
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21102680 times.
21102680 if (FFCore.doesResolveToDeprecatedSystemBitmap(bitmap_id))
21696 return {DrawOrigin::Screen, 0};
21697
21698
2/2
✓ Branch 0 taken 9700982 times.
✓ Branch 1 taken 11401698 times.
21102680 if (FFCore.doesResolveToScreenBitmap(bitmap_id))
21699 9700982 return {get_draw_origin_for_screen_draw_command(), ri->screen_draw_origin_target};
21700
21701
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11401698 times.
11401698 if (!is_screen_draw)
21702 11401698 return {get_draw_origin_for_bitmap_draw_command(), 0};
21703
21704 return {DrawOrigin::Screen, 0};
21705 120288488 }
21706
21707 118678442 static void do_drawing_command(int32_t script_command, bool is_screen_draw)
21708 {
21709
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 118678442 times.
118678442 if (FFCore.skipscriptdraws)
21710 return;
21711
21712 118678442 int32_t j = script_drawing_commands.GetNext();
21713
1/2
✓ Branch 0 taken 118678442 times.
✗ Branch 1 not taken.
118678442 if(j == -1) //out of drawing command space
21714 {
21715 Z_scripterrlog("Max draw primitive limit reached\n");
21716 return;
21717 }
21718
21719 118678442 script_drawing_commands[j] = {};
21720 118678442 script_drawing_commands[j][0] = script_command;
21721 118678442 script_drawing_commands[j][DRAWCMD_CURRENT_TARGET] = zscriptDrawingRenderTarget->GetCurrentRenderTarget();
21722
21723
39/80
✗ Branch 0 not taken.
✓ Branch 1 taken 3699 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 7323 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3196522 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1096478 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1850 times.
✓ Branch 11 taken 2356839 times.
✓ Branch 12 taken 383247 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 1080 times.
✓ Branch 18 taken 2178024 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 2714863 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 5169752 times.
✓ Branch 23 taken 28377891 times.
✓ Branch 24 taken 964155 times.
✓ Branch 25 taken 148476 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 9270 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 904749 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 4170317 times.
✓ Branch 32 taken 49606 times.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✓ Branch 35 taken 1568537 times.
✓ Branch 36 taken 190166 times.
✓ Branch 37 taken 12431 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 1898473 times.
✓ Branch 40 taken 34749 times.
✓ Branch 41 taken 26757 times.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✓ Branch 45 taken 186027 times.
✗ Branch 46 not taken.
✓ Branch 47 taken 502 times.
✓ Branch 48 taken 144 times.
✗ Branch 49 not taken.
✓ Branch 50 taken 80910 times.
✓ Branch 51 taken 64479 times.
✗ Branch 52 not taken.
✓ Branch 53 taken 11288 times.
✗ Branch 54 not taken.
✓ Branch 55 taken 1802707 times.
✓ Branch 56 taken 39064775 times.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✓ Branch 59 taken 865 times.
✓ Branch 60 taken 45504 times.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
✓ Branch 65 taken 143658 times.
✓ Branch 66 taken 1876122 times.
✓ Branch 67 taken 113653 times.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✓ Branch 73 taken 19821648 times.
✗ Branch 74 not taken.
✓ Branch 75 taken 906 times.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
118678442 switch(script_command)
21724 {
21725 case RECTR:
21726 3196522 set_drawing_command_args(j, 12);
21727 3196522 break;
21728
21729 case FRAMER:
21730 set_drawing_command_args(j, 9);
21731 break;
21732
21733 case CIRCLER:
21734 1096478 set_drawing_command_args(j, 11);
21735 1096478 break;
21736
21737 case ARCR:
21738 set_drawing_command_args(j, 14);
21739 break;
21740
21741 case ELLIPSER:
21742 1850 set_drawing_command_args(j, 12);
21743 1850 break;
21744
21745 case LINER:
21746 2356839 set_drawing_command_args(j, 11);
21747 2356839 break;
21748
21749 case PUTPIXELR:
21750 383247 set_drawing_command_args(j, 8);
21751 383247 break;
21752
21753 case PIXELARRAYR:
21754 {
21755 set_drawing_command_args(j, 5);
21756 std::vector<int32_t> *v = script_drawing_commands.GetVector();
21757
21758 int32_t arrayptr = script_drawing_commands[j][2];
21759 if ( !arrayptr ) //Don't crash because of vector size.
21760 {
21761 Z_scripterrlog("Invalid array pointer %d passed to Screen->PutPixels(). Aborting.", arrayptr);
21762 break;
21763 }
21764 int32_t sz = ArrayH::getSize(arrayptr);
21765 if(sz <= 0)
21766 {
21767 script_drawing_commands.PopLast();
21768 return;
21769 }
21770 v->resize(sz, 0);
21771 int32_t* pos = &v->at(0);
21772
21773 ArrayH::getValues(script_drawing_commands[j][2], pos, sz);
21774 script_drawing_commands[j].SetVector(v);
21775 break;
21776 }
21777
21778 case TILEARRAYR:
21779 {
21780 set_drawing_command_args(j, 2);
21781 std::vector<int32_t> *v = script_drawing_commands.GetVector();
21782
21783 int32_t arrayptr = script_drawing_commands[j][2];
21784 if ( !arrayptr ) //Don't crash because of vector size.
21785 {
21786 Z_scripterrlog("Invalid array pointer %d passed to Screen->DrawTiles(). Aborting.", arrayptr);
21787 break;
21788 }
21789 int32_t sz = ArrayH::getSize(arrayptr);
21790 if(sz <= 0)
21791 {
21792 script_drawing_commands.PopLast();
21793 return;
21794 }
21795 v->resize(sz, 0);
21796 int32_t* pos = &v->at(0);
21797
21798 ArrayH::getValues(script_drawing_commands[j][2], pos, sz);
21799 script_drawing_commands[j].SetVector(v);
21800 break;
21801 }
21802
21803 case LINESARRAY:
21804 {
21805 set_drawing_command_args(j, 2);
21806 std::vector<int32_t> *v = script_drawing_commands.GetVector();
21807
21808 int32_t arrayptr = script_drawing_commands[j][2];
21809 if ( !arrayptr ) //Don't crash because of vector size.
21810 {
21811 Z_scripterrlog("Invalid array pointer %d passed to Screen->Lines(). Aborting.", arrayptr);
21812 break;
21813 }
21814 int32_t sz = ArrayH::getSize(arrayptr);
21815 if(sz <= 0)
21816 {
21817 script_drawing_commands.PopLast();
21818 return;
21819 }
21820 v->resize(sz, 0);
21821 int32_t* pos = &v->at(0);
21822
21823 ArrayH::getValues(script_drawing_commands[j][2], pos, sz);
21824 script_drawing_commands[j].SetVector(v);
21825 break;
21826 }
21827
21828 case COMBOARRAYR:
21829 {
21830 set_drawing_command_args(j, 2);
21831 std::vector<int32_t> *v = script_drawing_commands.GetVector();
21832 int32_t arrayptr = script_drawing_commands[j][2];
21833 if ( !arrayptr ) //Don't crash because of vector size.
21834 {
21835 Z_scripterrlog("Invalid array pointer %d passed to Screen->DrawCombos(). Aborting.", arrayptr);
21836 break;
21837 }
21838 int32_t sz = ArrayH::getSize(arrayptr);
21839 if(sz <= 0)
21840 {
21841 script_drawing_commands.PopLast();
21842 return;
21843 }
21844 v->resize(sz, 0);
21845 int32_t* pos = &v->at(0);
21846
21847 ArrayH::getValues(script_drawing_commands[j][2], pos, sz);
21848 script_drawing_commands[j].SetVector(v);
21849 break;
21850 }
21851 case POLYGONR:
21852 {
21853 1080 set_drawing_command_args(j, 5);
21854
21855 1080 int32_t arrayptr = script_drawing_commands[j][3];
21856
1/2
✓ Branch 0 taken 1080 times.
✗ Branch 1 not taken.
1080 if ( !arrayptr ) //Don't crash because of vector size.
21857 {
21858 Z_scripterrlog("Invalid array pointer %d passed to Screen->Polygon(). Aborting.", arrayptr);
21859 break;
21860 }
21861 1080 int32_t sz = ArrayH::getSize(arrayptr);
21862
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1080 times.
1080 if(sz <= 0)
21863 {
21864 script_drawing_commands.PopLast();
21865 return;
21866 }
21867
21868 1080 std::vector<int32_t> *v = script_drawing_commands.GetVector();
21869 1080 v->resize(sz, 0);
21870
21871 1080 int32_t* pos = &v->at(0);
21872
21873
21874 1080 ArrayH::getValues(script_drawing_commands[j][3], pos, sz);
21875 1080 script_drawing_commands[j].SetVector(v);
21876 }
21877 1080 break;
21878
21879 case DRAWTILER:
21880 2178024 set_drawing_command_args(j, 15);
21881 2178024 break;
21882
21883 case DRAWTILECLOAKEDR:
21884 set_drawing_command_args(j, 7);
21885 break;
21886
21887 case DRAWCOMBOR:
21888 2714863 set_drawing_command_args(j, 16);
21889 2714863 break;
21890
21891 case DRAWCOMBOCLOAKEDR:
21892 set_drawing_command_args(j, 7);
21893 break;
21894
21895 case FASTTILER:
21896 5169752 set_drawing_command_args(j, 6);
21897 5169752 break;
21898
21899 case FASTCOMBOR:
21900 28377891 set_drawing_command_args(j, 6);
21901 28377891 break;
21902
21903 case DRAWCHARR:
21904 964155 set_drawing_command_args(j, 10);
21905 964155 break;
21906
21907 case DRAWINTR:
21908 148476 set_drawing_command_args(j, 11);
21909 148476 break;
21910
21911 case SPLINER:
21912 set_drawing_command_args(j, 11);
21913 break;
21914
21915 case QUADR:
21916 9270 set_drawing_command_args(j, 15);
21917 9270 break;
21918
21919 case TRIANGLER:
21920 set_drawing_command_args(j, 13);
21921 break;
21922
21923 case BITMAPR:
21924 904749 set_drawing_command_args(j, 12);
21925 904749 break;
21926
21927 case BITMAPEXR:
21928 set_drawing_command_args(j, 16);
21929 break;
21930
21931 case DRAWLAYERR:
21932 4170317 set_drawing_command_args(j, 8);
21933 4170317 break;
21934
21935 case DRAWSCREENR:
21936 49606 set_drawing_command_args(j, 6);
21937 49606 break;
21938
21939 case QUAD3DR:
21940 {
21941 set_drawing_command_args(j, 8);
21942 int32_t arrayptr = script_drawing_commands[j][2];
21943 int32_t sz = ArrayH::getSize(arrayptr);
21944 arrayptr = script_drawing_commands[j][3];
21945 sz += ArrayH::getSize(arrayptr);
21946 arrayptr = script_drawing_commands[j][4];
21947 sz += ArrayH::getSize(arrayptr);
21948 arrayptr = script_drawing_commands[j][5];
21949 sz += ArrayH::getSize(arrayptr);
21950 if(sz < 25)
21951 {
21952 script_drawing_commands.PopLast();
21953 return;
21954 }
21955 std::vector<int32_t> *v = script_drawing_commands.GetVector();
21956 v->resize(sz, 0);
21957
21958 int32_t* pos = &v->at(0);
21959 int32_t* uv = &v->at(12);
21960 int32_t* col = &v->at(20);
21961 int32_t* size = &v->at(24);
21962
21963 ArrayH::getValues((script_drawing_commands[j][2]), pos, 12);
21964 ArrayH::getValues((script_drawing_commands[j][3]), uv, 8);
21965 ArrayH::getValues((script_drawing_commands[j][4]), col, 4);
21966 //FFCore.getValues2(script_drawing_commands[j][5], size, 2);
21967 ArrayH::getValues((script_drawing_commands[j][5]), size, 2);
21968
21969 script_drawing_commands[j].SetVector(v);
21970 }
21971 break;
21972
21973 case TRIANGLE3DR:
21974 {
21975 set_drawing_command_args(j, 8);
21976
21977 int32_t arrayptr = script_drawing_commands[j][2];
21978 int32_t sz = ArrayH::getSize(arrayptr);
21979 arrayptr = script_drawing_commands[j][3];
21980 sz += ArrayH::getSize(arrayptr);
21981 arrayptr = script_drawing_commands[j][4];
21982 sz += ArrayH::getSize(arrayptr);
21983 arrayptr = script_drawing_commands[j][5];
21984 sz += ArrayH::getSize(arrayptr);
21985 if(sz < 19)
21986 {
21987 script_drawing_commands.PopLast();
21988 return;
21989 }
21990
21991 std::vector<int32_t> *v = script_drawing_commands.GetVector();
21992 v->resize(sz, 0);
21993
21994 int32_t* pos = &v->at(0);
21995 int32_t* uv = &v->at(9);
21996 int32_t* col = &v->at(15);
21997 int32_t* size = &v->at(18);
21998
21999 ArrayH::getValues(script_drawing_commands[j][2], pos, 8);
22000 ArrayH::getValues(script_drawing_commands[j][3], uv, 6);
22001 ArrayH::getValues(script_drawing_commands[j][4], col, 3);
22002 ArrayH::getValues(script_drawing_commands[j][5], size, 2);
22003
22004 script_drawing_commands[j].SetVector(v);
22005 }
22006 break;
22007
22008 case DRAWSTRINGR:
22009 {
22010 1568537 set_drawing_command_args(j, 9);
22011 // Unused
22012 //const int32_t index = script_drawing_commands[j][19] = j;
22013
22014 1568537 string *str = script_drawing_commands.GetString();
22015 1568537 ArrayH::getString(script_drawing_commands[j][8], *str, 256);
22016 1568537 script_drawing_commands[j].SetString(str);
22017 }
22018 1568537 break;
22019
22020 case DRAWSTRINGR2:
22021 {
22022 190166 set_drawing_command_args(j, 11);
22023 // Unused
22024 //const int32_t index = script_drawing_commands[j][19] = j;
22025
22026 190166 string *str = script_drawing_commands.GetString();
22027 190166 ArrayH::getString(script_drawing_commands[j][8], *str, 256);
22028 190166 script_drawing_commands[j].SetString(str);
22029 }
22030 190166 break;
22031
22032 case BMPRECTR:
22033 12431 set_user_bitmap_command_args(j, 12); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+12);
22034 //Pop the args off the stack first. Then pop the pointer and push it to sdci[17].
22035 //The pointer for the bitmap variable (its literal value) is always ri->sp+numargs, so, with 12 args, it is sp+12.
22036 12431 break;
22037
22038 case BMPFRAMER:
22039 set_user_bitmap_command_args(j, 9);
22040 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+9);
22041 break;
22042
22043 case CLEARBITMAP:
22044 {
22045 1898473 set_user_bitmap_command_args(j, 1);
22046 1898473 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+1);
22047 1898473 break;
22048 }
22049 case BITMAPCLEARTOCOLOR:
22050 {
22051 34749 set_user_bitmap_command_args(j, 2);
22052 34749 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+2);
22053 34749 break;
22054 }
22055 case REGENERATEBITMAP:
22056 {
22057 26757 set_user_bitmap_command_args(j, 3);
22058 26757 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+3);
22059 26757 break;
22060 }
22061 case BMPPOLYGONR:
22062 {
22063 set_user_bitmap_command_args(j, 5);
22064 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+5);
22065 int32_t arrayptr = script_drawing_commands[j][3];
22066 if ( !arrayptr ) //Don't crash because of vector size.
22067 {
22068 Z_scripterrlog("Invalid array pointer %d passed to Screen->Polygon(). Aborting.", arrayptr);
22069 break;
22070 }
22071 int32_t sz = ArrayH::getSize(arrayptr);
22072 if(sz <= 0)
22073 {
22074 script_drawing_commands.PopLast();
22075 return;
22076 }
22077 std::vector<int32_t> *v = script_drawing_commands.GetVector();
22078 v->resize(sz, 0);
22079
22080 int32_t* pos = &v->at(0);
22081
22082
22083 ArrayH::getValues(script_drawing_commands[j][3], pos, sz);
22084 script_drawing_commands[j].SetVector(v);
22085 }
22086 break;
22087 case READBITMAP:
22088 {
22089 set_user_bitmap_command_args(j, 2);
22090 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+2);
22091 string& user_path = *script_drawing_commands.GetString();
22092 ArrayH::getString(script_drawing_commands[j][2], user_path, 256);
22093
22094 if (get_qr(qr_BITMAP_AND_FILESYSTEM_PATHS_ALWAYS_RELATIVE))
22095 {
22096 if (auto r = parse_user_path(user_path, true); !r)
22097 {
22098 scripting_log_error_with_context("Error: {}", r.error());
22099 return;
22100 } else user_path = r.value();
22101 }
22102 else
22103 {
22104 regulate_path(user_path);
22105 }
22106
22107 script_drawing_commands[j].SetString(&user_path);
22108 break;
22109 }
22110 case WRITEBITMAP:
22111 {
22112 set_user_bitmap_command_args(j, 3);
22113 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+3);
22114 std::string& user_path = *script_drawing_commands.GetString();
22115 ArrayH::getString(script_drawing_commands[j][2], user_path, 256);
22116
22117 if (get_qr(qr_BITMAP_AND_FILESYSTEM_PATHS_ALWAYS_RELATIVE))
22118 {
22119 if (auto r = parse_user_path(user_path, true); !r)
22120 {
22121 scripting_log_error_with_context("Error: {}", r.error());
22122 return;
22123 } else user_path = r.value();
22124 }
22125 else
22126 {
22127 regulate_path(user_path);
22128 }
22129
22130 script_drawing_commands[j].SetString(&user_path);
22131 break;
22132 }
22133
22134 186027 case BMPCIRCLER: set_user_bitmap_command_args(j, 11); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+11); break;
22135 case BMPARCR: set_user_bitmap_command_args(j, 14); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+14); break;
22136 502 case BMPELLIPSER: set_user_bitmap_command_args(j, 12); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+12); break;
22137 144 case BMPLINER: set_user_bitmap_command_args(j, 11); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+11); break;
22138 case BMPSPLINER: set_user_bitmap_command_args(j, 11); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+11); break;
22139 80910 case BMPPUTPIXELR: set_user_bitmap_command_args(j, 8); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+8); break;
22140 64479 case BMPDRAWTILER: set_user_bitmap_command_args(j, 15); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+15); break;
22141 case BMPDRAWTILECLOAKEDR: set_user_bitmap_command_args(j, 7); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+7); break;
22142 11288 case BMPDRAWCOMBOR: set_user_bitmap_command_args(j, 16); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+16); break;
22143 case BMPDRAWCOMBOCLOAKEDR: set_user_bitmap_command_args(j, 7); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+7); break;
22144 1802707 case BMPFASTTILER: set_user_bitmap_command_args(j, 6); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+6); break;
22145 39064775 case BMPFASTCOMBOR: set_user_bitmap_command_args(j, 6); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+6); break;
22146 case BMPDRAWCHARR: set_user_bitmap_command_args(j, 10); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+10); break;
22147 case BMPDRAWINTR: set_user_bitmap_command_args(j, 11); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+11); break;
22148 case BMPDRAWSTRINGR:
22149 {
22150 865 set_user_bitmap_command_args(j, 9);
22151 865 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+9);
22152 // Unused
22153 //const int32_t index = script_drawing_commands[j][19] = j;
22154
22155 865 string *str = script_drawing_commands.GetString();
22156 865 ArrayH::getString(script_drawing_commands[j][8], *str, 256);
22157 865 script_drawing_commands[j].SetString(str);
22158
22159 }
22160 865 break;
22161 case BMPDRAWSTRINGR2:
22162 {
22163 45504 set_user_bitmap_command_args(j, 11);
22164 45504 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+11);
22165 // Unused
22166 //const int32_t index = script_drawing_commands[j][19] = j;
22167
22168 45504 string *str = script_drawing_commands.GetString();
22169 45504 ArrayH::getString(script_drawing_commands[j][8], *str, 256);
22170 45504 script_drawing_commands[j].SetString(str);
22171
22172 }
22173 45504 break;
22174 case BMPQUADR: set_user_bitmap_command_args(j, 16); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+16); break;
22175 case BMPQUAD3DR:
22176 {
22177 set_drawing_command_args(j, 9);
22178 std::vector<int32_t> *v = script_drawing_commands.GetVector();
22179 v->resize(26, 0);
22180
22181 int32_t* pos = &v->at(0);
22182 int32_t* uv = &v->at(12);
22183 int32_t* col = &v->at(20);
22184 int32_t* size = &v->at(24);
22185
22186
22187 ArrayH::getValues(script_drawing_commands[j][2], pos, 12);
22188 ArrayH::getValues(script_drawing_commands[j][3], uv, 8);
22189 ArrayH::getValues(script_drawing_commands[j][4], col, 4);
22190 ArrayH::getValues(script_drawing_commands[j][5], size, 2);
22191
22192 script_drawing_commands[j].SetVector(v);
22193 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+9);
22194
22195 }
22196 break;
22197 case BMPTRIANGLER: set_user_bitmap_command_args(j, 14); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+14); break;
22198 case BMPTRIANGLE3DR:
22199 {
22200 set_drawing_command_args(j, 9);
22201
22202 std::vector<int32_t> *v = script_drawing_commands.GetVector();
22203 v->resize(20, 0);
22204
22205 int32_t* pos = &v->at(0);
22206 int32_t* uv = &v->at(9);
22207 int32_t* col = &v->at(15);
22208 int32_t* size = &v->at(18);
22209
22210
22211 ArrayH::getValues(script_drawing_commands[j][2], pos, 8);
22212 ArrayH::getValues(script_drawing_commands[j][3], uv, 6);
22213 ArrayH::getValues(script_drawing_commands[j][4], col, 3);
22214 ArrayH::getValues(script_drawing_commands[j][5], size, 2);
22215
22216 script_drawing_commands[j].SetVector(v);
22217 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+9);
22218 break;
22219 }
22220
22221 case BMPDRAWLAYERR:
22222 143658 set_user_bitmap_command_args(j, 8);
22223 143658 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+8);
22224 143658 break;
22225 case BMPDRAWLAYERSOLIDR:
22226 case BMPDRAWLAYERCFLAGR:
22227 case BMPDRAWLAYERCTYPER:
22228 case BMPDRAWLAYERCIFLAGR:
22229 case BMPDRAWLAYERSOLIDITYR: set_user_bitmap_command_args(j, 9); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+9); break;
22230 case BMPDRAWSCREENR:
22231 case BMPDRAWSCREENSOLIDR:
22232 case BMPDRAWSCREENSOLID2R:
22233 case BMPDRAWSCREENCOMBOFR:
22234 case BMPDRAWSCREENCOMBOIR:
22235 case BMPDRAWSCREENCOMBOTR:
22236 3699 set_user_bitmap_command_args(j, 6); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+6); break;
22237 case BMPBLIT:
22238 {
22239 1876122 set_user_bitmap_command_args(j, 16);
22240
22241 1876122 int bmp_target = SH::read_stack(ri->sp+16);
22242 1876122 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = bmp_target;
22243
22244
2/2
✓ Branch 0 taken 266080 times.
✓ Branch 1 taken 1610042 times.
1876122 if (!get_qr(qr_BROKEN_SCRIPTS_BITMAP_DRAW_ORIGIN))
22245 {
22246 1610042 int bmp_dest = script_drawing_commands[j][2];
22247 3220084 auto [draw_origin, draw_origin_target] = get_draw_origin_for_draw_command(is_screen_draw, bmp_dest);
22248 1610042 script_drawing_commands[j].secondary_draw_origin = draw_origin;
22249 1610042 script_drawing_commands[j].secondary_draw_origin_target = draw_origin_target;
22250 1610042 }
22251 1876122 break;
22252 }
22253 case BMPBLITTO:
22254 {
22255 113653 set_user_bitmap_command_args(j, 16);
22256 113653 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+16);
22257
22258
2/2
✓ Branch 0 taken 113649 times.
✓ Branch 1 taken 4 times.
113653 if (!get_qr(qr_BROKEN_SCRIPTS_BITMAP_DRAW_ORIGIN))
22259 {
22260 4 int bmp_source = script_drawing_commands[j][2];
22261 8 auto [draw_origin, draw_origin_target] = get_draw_origin_for_draw_command(is_screen_draw, bmp_source);
22262 4 script_drawing_commands[j].secondary_draw_origin = draw_origin;
22263 4 script_drawing_commands[j].secondary_draw_origin_target = draw_origin_target;
22264 4 }
22265 113653 break;
22266 }
22267 case TILEBLIT:
22268 {
22269 set_drawing_command_args(j, 17);
22270 break;
22271 }
22272 case COMBOBLIT:
22273 {
22274 set_drawing_command_args(j, 17);
22275 break;
22276 }
22277 case BMPTILEBLIT:
22278 {
22279 set_user_bitmap_command_args(j, 17);
22280 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+17);
22281 break;
22282 }
22283 case BMPCOMBOBLIT:
22284 {
22285 set_user_bitmap_command_args(j, 17);
22286 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+17);
22287 break;
22288 }
22289 case BMPMODE7:
22290 {
22291 set_user_bitmap_command_args(j, 13);
22292 //for(int32_t q = 0; q < 8; ++q )
22293 //Z_scripterrlog("FFscript blit() ri->d[%d] is: %d\n", q, ri->d[q]);
22294 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+13);
22295 break;
22296 }
22297
22298 case BMPWRITETILE:
22299 {
22300 19821648 set_user_bitmap_command_args(j, 6);
22301 19821648 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+6);
22302 19821648 break;
22303 }
22304 case BMPDITHER:
22305 {
22306 set_user_bitmap_command_args(j, 5);
22307 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+5);
22308 break;
22309 }
22310 case BMPMASKDRAW:
22311 {
22312 906 set_user_bitmap_command_args(j, 3);
22313 906 script_drawing_commands[j][4] = 0x01 * 10000L;
22314 906 script_drawing_commands[j][5] = 0xFF * 10000L;
22315 906 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+3);
22316 906 break;
22317 }
22318 case BMPMASKDRAW2:
22319 {
22320 set_user_bitmap_command_args(j, 4);
22321 script_drawing_commands[j][5] = script_drawing_commands[j][4];
22322 script_drawing_commands[j][0] = BMPMASKDRAW;
22323 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+4);
22324 break;
22325 }
22326 case BMPMASKDRAW3:
22327 {
22328 set_user_bitmap_command_args(j, 5);
22329 script_drawing_commands[j][0] = BMPMASKDRAW;
22330 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+5);
22331 break;
22332 }
22333 case BMPMASKBLIT:
22334 {
22335 set_user_bitmap_command_args(j, 4);
22336 script_drawing_commands[j][5] = 0x01 * 10000L;
22337 script_drawing_commands[j][6] = 0xFF * 10000L;
22338 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+4);
22339 break;
22340 }
22341 case BMPMASKBLIT2:
22342 {
22343 set_user_bitmap_command_args(j, 5);
22344 script_drawing_commands[j][6] = script_drawing_commands[j][5];
22345 script_drawing_commands[j][0] = BMPMASKBLIT;
22346 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+5);
22347 break;
22348 }
22349 case BMPMASKBLIT3:
22350 {
22351 set_user_bitmap_command_args(j, 6);
22352 script_drawing_commands[j][0] = BMPMASKBLIT;
22353 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+6);
22354 break;
22355 }
22356 case BMPREPLCOLOR:
22357 case BMPSHIFTCOLOR:
22358 {
22359 7323 set_user_bitmap_command_args(j, 4);
22360 7323 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+4);
22361 7323 break;
22362 }
22363
22364 case DRAWLIGHT_CONE:
22365 case DRAWLIGHT_CIRCLE:
22366 case DRAWLIGHT_SQUARE:
22367 {
22368 // These draw commands implicitly draw at the SPLAYER_DARKROOM_UNDER timing.
22369 // Shift the given args up by one.
22370 int num_args = script_command == DRAWLIGHT_CONE ? 8 : 7;
22371 set_drawing_command_args(j, num_args);
22372 for (int i = num_args; i >= 1; i--)
22373 script_drawing_commands[j][i + 1] = script_drawing_commands[j][i];
22374 script_drawing_commands[j][1] = SPLAYER_DARKROOM_UNDER * 10000;
22375 break;
22376 }
22377 }
22378
22379 int bmp_target;
22380
2/2
✓ Branch 0 taken 53527326 times.
✓ Branch 1 taken 65151116 times.
118678442 if (is_screen_draw)
22381 53527326 bmp_target = zscriptDrawingRenderTarget->GetCurrentRenderTarget() + 10;
22382 else
22383 65151116 bmp_target = script_drawing_commands[j][DRAWCMD_BMP_TARGET];
22384
22385 237356884 auto [draw_origin, draw_origin_target] = get_draw_origin_for_draw_command(is_screen_draw, bmp_target);
22386 118678442 script_drawing_commands[j].draw_origin = draw_origin;
22387 118678442 script_drawing_commands[j].draw_origin_target = draw_origin_target;
22388
22389 118678442 script_drawing_commands.mark_dirty(script_drawing_commands[j][1]/10000);
22390 118678442 }
22391
22392 7084216 void do_set_rendertarget(bool)
22393 {
22394 7084216 int32_t target = int32_t(SH::read_stack(ri->sp) / 10000);
22395 7084216 zscriptDrawingRenderTarget->SetCurrentRenderTarget(target);
22396 7084216 }
22397
22398 427914 void do_sfx(const bool v)
22399 {
22400 427914 int32_t ID = SH::get_arg(sarg1, v) / 10000;
22401
22402
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 427910 times.
427914 if(BC::checkSFXID(ID) != SH::_NoError)
22403 4 return;
22404
22405 427910 sfx(ID);
22406 427914 }
22407
22408 14 void do_sfx_ex(const bool restart)
22409 {
22410 14 int32_t ID = SH::read_stack(ri->sp + 4) / 10000;
22411 14 zfix vol = vbound(zslongToFix(SH::read_stack(ri->sp + 3)), 0_zf, 100_zf);
22412 14 int32_t pan = vbound(SH::read_stack(ri->sp + 2)/10000 + 128, 0, 255);
22413 14 int32_t freq = SH::read_stack(ri->sp + 1);
22414 14 bool loop = SH::read_stack(ri->sp) / 10000;
22415
22416
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (BC::checkSFXID(ID) != SH::_NoError)
22417 return;
22418
22419
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14 if (!restart && !sfx_allocated(ID))
22420 return;
22421
22422 14 sfx(ID, pan, loop, restart, vol, freq);
22423 14 }
22424
22425 static int get_sfx_completion()
22426 {
22427 int32_t ID = get_register(sarg1) / 10000;
22428
22429 if (!sfx_allocated(ID))
22430 {
22431 return -10000;
22432 }
22433
22434 int sample_pos = voice_get_position(sfx_voice[ID]);
22435 if (sample_pos < 0)
22436 {
22437 return -10000;
22438 }
22439
22440 uint32_t sample_length = sfx_get_length(ID);
22441 uint64_t res = ((uint64_t)sample_pos * 10000 * 100) / sample_length;
22442 return int32_t(res);
22443 }
22444
22445 void do_get_sfx_completion()
22446 {
22447 int32_t ID = get_register(sarg1) / 10000;
22448 if (replay_is_active())
22449 replay_step_comment(fmt::format("ID {}", ID));
22450 int32_t value = replay_get_state(ReplayStateType::SfxPosition, get_sfx_completion);
22451 set_register(sarg1, value);
22452 }
22453
22454 void FFScript::AlloffLimited(int32_t flagset)
22455 {
22456 clear_bitmap(msg_txt_display_buf);
22457 clear_bitmap(msg_bg_display_buf);
22458 clear_bitmap(msg_portrait_display_buf);
22459 set_clip_state(msg_txt_display_buf, 1);
22460 set_clip_state(msg_bg_display_buf, 1);
22461 set_clip_state(msg_portrait_display_buf, 1);
22462
22463
22464 clear_bitmap(pricesdisplaybuf);
22465 set_clip_state(pricesdisplaybuf, 1);
22466
22467 if(items.idCount(iPile))
22468 {
22469 loadlvlpal(DMaps[cur_dmap].color);
22470 }
22471
22472 /*
22473
22474 #define warpFlagCLEARITEMS 0x200
22475 #define warpFlagCLEARGUYS 0x400
22476 #define warpFlagCLEARLWEAPONS 0x800
22477 #define warpFlagCLEAREWEAPONS 0x1000
22478 #define warpFlagCLEARHOOKSHOT 0x2000
22479 #define warpFlagCLEARDECORATIONS 0x4000
22480 #define warpFlagCLEARPARTICLES 0x8000
22481 */
22482
22483 if ( (flagset&warpFlagCLEARITEMS) ) items.clear();
22484 if ( (flagset&warpFlagCLEARGUYS) ) guys.clear();
22485 if ( (flagset&warpFlagCLEARLWEAPONS) ) Lwpns.clear();
22486 if ( (flagset&warpFlagCLEAREWEAPONS) ) Ewpns.clear();
22487 if ( (flagset&warpFlagCLEARHOOKSHOT) )
22488 {
22489 chainlinks.clear();
22490 Hero.reset_hookshot();
22491 }
22492 if ( (flagset&warpFlagCLEARDECORATIONS) ) decorations.clear();
22493 if ( (flagset&warpFlagCLEARPARTICLES) ) particles.clear();
22494 clearScriptHelperData();
22495
22496
22497
22498 clearScriptHelperData();
22499
22500 lensclk = 0;
22501 lensid=-1;
22502 drawguys=true;
22503 down_control_states[btnUp] =
22504 down_control_states[btnDown] =
22505 down_control_states[btnLeft] =
22506 down_control_states[btnRight] =
22507 down_control_states[btnA] =
22508 down_control_states[btnB] =
22509 down_control_states[btnS] = true;
22510
22511 if(watch && !cheat_superman)
22512 {
22513 Hero.setClock(false);
22514 }
22515
22516 watch=freeze_guys=loaded_guys=blockpath=false;
22517
22518 activation_counters.fill({});
22519 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
22520 get_screen_state(scr->screen).loaded_enemies = false;
22521 });
22522
22523 sle_clk=0;
22524
22525 if(usebombpal)
22526 {
22527 memcpy(RAMpal, tempbombpal, PAL_SIZE*sizeof(RGB));
22528 refreshpal=true;
22529 usebombpal=false;
22530 }
22531
22532
22533 }
22534
22535 210 void doWarpEffect(int32_t warpEffect, bool out)
22536 {
22537
4/6
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 158 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 34 times.
✓ Branch 5 taken 10 times.
210 switch(warpEffect)
22538 {
22539 case warpEffectZap:
22540 if(out) zapout();
22541 else zapin();
22542 break;
22543 case warpEffectWave:
22544
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 17 times.
34 if(out) wavyout(false);
22545 17 else wavyin();
22546 34 break;
22547 case warpEffectInstant:
22548
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if(out) blackscr(30,true);
22549 8 break;
22550 case warpEffectMozaic:
22551 //!TODO Unimplemented
22552 break;
22553 case warpEffectOpen:
22554
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 if(out) closescreen();
22555 5 else openscreen();
22556 10 break;
22557 }
22558 210 }
22559
22560 14 void FFScript::queueWarp(int32_t wtype, int32_t tdm, int32_t tscr, int32_t wx, int32_t wy,
22561 int32_t weff, int32_t wsfx, int32_t wflag, int32_t wdir)
22562 {
22563 14 warpex[wexActive] = 1;
22564 14 warpex[wexType] = wtype;
22565 14 warpex[wexDMap] = tdm;
22566 14 warpex[wexScreen] = tscr;
22567 14 warpex[wexX] = wx;
22568 14 warpex[wexY] = wy;
22569 14 warpex[wexEffect] = weff;
22570 14 warpex[wexSound] = wsfx;
22571 14 warpex[wexFlags] = wflag;
22572 14 warpex[wexDir] = wdir;
22573 14 }
22574
22575 115 bool FFScript::warp_player(int32_t warpType, int32_t dmap, int32_t screen, int32_t warpDestX, int32_t warpDestY, int32_t warpEffect, int32_t warpSound, int32_t warpFlags, int32_t heroFacesDir)
22576 {
22577 if(DEVLOGGING)
22578 {
22579 zprint("FFScript::warp_player() arg %s is: %d \n", "warpType", warpType);
22580 zprint("FFScript::warp_player() arg %s is: %d \n", "dmap", dmap);
22581 zprint("FFScript::warp_player() arg %s is: %d \n", "screen", screen);
22582 zprint("FFScript::warp_player() arg %s is: %d \n", "warpDestX", warpDestX);
22583 zprint("FFScript::warp_player() arg %s is: %d \n", "warpDestY", warpDestY);
22584 zprint("FFScript::warp_player() arg %s is: %d \n", "warpEffect", warpEffect);
22585 zprint("FFScript::warp_player() arg %s is: %d \n", "warpSound", warpSound);
22586 zprint("FFScript::warp_player() arg %s is: %d \n", "warpFlags", warpFlags);
22587 zprint("FFScript::warp_player() arg %s is: %d \n", "heroFacesDir", heroFacesDir);
22588 }
22589
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 115 times.
115 if ( ((unsigned)dmap) >= MAXDMAPS )
22590 {
22591 Z_scripterrlog("Invalid DMap ID (%d) passed to WarpEx(). Aborting.\n", dmap);
22592 return false;
22593 }
22594
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 115 times.
115 if ( ((unsigned)screen) >= MAPSCRS )
22595 {
22596 Z_scripterrlog("Invalid Screen Index (%d) passed to WarpEx(). Aborting.\n", screen);
22597 return false;
22598 }
22599 //Extra sanity guard.
22600
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 115 times.
115 if ( map_screen_index(DMaps[dmap].map, screen + DMaps[dmap].xoff) >= (int32_t)TheMaps.size() )
22601 {
22602 Z_scripterrlog("Invalid destination passed to WarpEx(). Aborting.\n");
22603 return false;
22604 }
22605 115 byte t = 0;
22606 115 t=(cur_screen<128)?0:1;
22607 115 bool overlay=false;
22608 115 bool intradmap = (dmap == cur_dmap);
22609 115 int32_t olddmap = cur_dmap;
22610 //if ( intradmap )
22611 //{
22612 // initZScriptDMapScripts(); //Not needed.
22613 //}
22614
22615
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 115 times.
115 if ( warpType == wtNOWARP ) { Z_eventlog("Used a Cancel Warped to DMap %d: %s, screen %d", cur_dmap, DMaps[cur_dmap].name,cur_screen); return false; }
22616 115 int32_t dest_map = DMaps[dmap].map;
22617 115 int32_t mapID = dest_map + 1;
22618 115 int32_t dest_dmap_xoff = DMaps[dmap].xoff;
22619 115 int32_t dest_screen = dest_dmap_xoff + screen;
22620 //mapscr *m = &TheMaps[mapID * MAPSCRS + scrID];
22621
1/2
✓ Branch 0 taken 115 times.
✗ Branch 1 not taken.
115 mapscr *m = &TheMaps[(zc_max((mapID)-1,0) * MAPSCRS + dest_screen)];
22622
1/2
✓ Branch 0 taken 115 times.
✗ Branch 1 not taken.
115 if ( warpFlags&warpFlagNOSTEPFORWARD ) FFCore.temp_no_stepforward = 1;
22623 115 int32_t wx = 0, wy = 0;
22624
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 94 times.
115 if ( warpDestX < 0 )
22625 {
22626 if(DEVLOGGING) zprint("WarpEx() was set to warp return point:%d\n", warpDestY);
22627
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 10 times.
94 if ( (unsigned)warpDestY < 4 )
22628 {
22629 84 wx = m->warpreturnx[warpDestY];
22630 84 wy = m->warpreturny[warpDestY];
22631 if(DEVLOGGING)
22632 {
22633 zprint("WarpEx Return Point X is: %d\n",wx);
22634 zprint("WarpEx Return Point Y is: %d\n",wy);
22635 }
22636 84 }
22637 else
22638 {
22639
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
10 if ( warpDestY == 5 || warpDestY < 0)
22640 {
22641 //Pit warp
22642 10 wx = Hero.getX();
22643 10 wy = Hero.getY();
22644 10 }
22645 else
22646 {
22647 Z_scripterrlog("Invalid Warp Return Square Type (%d) provided as an arg to Hero->WarpEx().\n",warpDestY);
22648 return false;
22649 }
22650 }
22651 94 }
22652 else
22653 {
22654 region_t region;
22655 int rx, ry;
22656 21 calculate_region(dest_map, dest_screen, region, rx, ry);
22657
2/4
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 21 times.
21 if ( (unsigned)warpDestX < region.width && (unsigned)warpDestY < region.height )
22658 {
22659 21 wx = warpDestX;
22660 21 wy = warpDestY;
22661 21 }
22662 else
22663 {
22664 Z_scripterrlog("Invalid pixel coordinates of x = %d, y = %d, supplied to Hero->WarpEx()\n",warpDestX,warpDestY);
22665 return false;
22666 }
22667 }
22668 115 Hero.finish_auto_walk();
22669 //warp coordinates are wx, wy, not x, y! -Z
22670
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 61 times.
115 if ( !(warpFlags&warpFlagDONTKILLSCRIPTDRAWS) ) script_drawing_commands.Clear();
22671 //we also need to check if dmaps are sideview here! -Z
22672 //Likewise, we need to add that check to the normal Hero:;dowarp(0
22673 115 bool wasSideview = isSideViewGravity(t);
22674
22675 //int32_t last_entr_scr = -1;
22676 //int32_t last_entr_dmap = -1;
22677
22678
1/2
✓ Branch 0 taken 115 times.
✗ Branch 1 not taken.
115 if ( warpType < wtEXIT ) warpType = wtIWARP; //Sanity check. We can't use wtCave, or wtPassage, with scritped warps at present.
22679 115 Hero.is_warping = true;
22680
2/5
✓ Branch 0 taken 105 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
115 switch(warpType)
22681 {
22682 case wtIWARP:
22683 case wtIWARPBLK:
22684 case wtIWARPOPEN:
22685 case wtIWARPZAP:
22686 case wtIWARPWAVE:
22687 {
22688 105 bool wasswimming = (Hero.getAction()==swimming);
22689 105 bool wassideswim = (Hero.getAction()==sideswimming);
22690 105 int32_t olddiveclk = Hero.diveclk;
22691
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 105 times.
105 if ( !(warpFlags&warpFlagDONTCLEARSPRITES) )
22692 {
22693 105 ALLOFF();
22694 105 }
22695 else FFCore.AlloffLimited(warpFlags);
22696
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 86 times.
105 if (warpFlags&warpFlagFORCERESETMUSIC) music_stop();
22697
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 51 times.
105 if ( !(warpFlags&warpFlagDONTKILLSOUNDS) ) kill_sfx();
22698 105 sfx(warpSound);
22699
1/2
✓ Branch 0 taken 105 times.
✗ Branch 1 not taken.
105 if(wasswimming)
22700 {
22701 Hero.setAction(swimming); FFCore.setHeroAction(swimming);
22702 Hero.set_dive(olddiveclk);
22703 }
22704
1/2
✓ Branch 0 taken 105 times.
✗ Branch 1 not taken.
105 if(wassideswim)
22705 {
22706 Hero.setAction(sideswimming); FFCore.setHeroAction(sideswimming);
22707 Hero.set_dive(0);
22708 }
22709 105 doWarpEffect(warpEffect, true);
22710 105 int32_t c = DMaps[cur_dmap].color;
22711 105 bool changedlevel = false;
22712 105 bool changeddmap = false;
22713
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 75 times.
105 if(cur_dmap != dmap)
22714 {
22715 75 timeExitAllGenscript(GENSCR_ST_CHANGE_DMAP);
22716 75 changeddmap = true;
22717 75 }
22718
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 53 times.
105 if(dlevel != DMaps[dmap].level)
22719 {
22720 53 timeExitAllGenscript(GENSCR_ST_CHANGE_LEVEL);
22721 53 changedlevel = true;
22722 53 }
22723 105 dlevel = DMaps[dmap].level;
22724 105 cur_dmap = dmap;
22725
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 75 times.
105 if(changeddmap)
22726 {
22727 75 throwGenScriptEvent(GENSCR_EVENT_CHANGE_DMAP);
22728 75 }
22729
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 53 times.
105 if(changedlevel)
22730 {
22731 53 throwGenScriptEvent(GENSCR_EVENT_CHANGE_LEVEL);
22732 53 }
22733 105 cur_map = DMaps[cur_dmap].map;
22734 105 init_dmap();
22735 105 update_subscreens(dmap);
22736
22737 105 ringcolor(false);
22738
22739
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 71 times.
105 if(DMaps[cur_dmap].color != c)
22740 71 loadlvlpal(DMaps[cur_dmap].color);
22741
22742 105 lightingInstant(); // Also sets naturaldark
22743 105 int prev_screen = Hero.current_screen;
22744 105 loadscr(cur_dmap, screen + DMaps[cur_dmap].xoff, -1, overlay);
22745
22746 // In the case where we did not call ALLOFF, preserve the "enemies have spawned"
22747 // state for the new screen.
22748
1/2
✓ Branch 0 taken 105 times.
✗ Branch 1 not taken.
105 if (warpFlags&warpFlagDONTCLEARSPRITES)
22749 {
22750 if (get_screen_state(prev_screen).loaded_enemies)
22751 get_screen_state(Hero.current_screen).loaded_enemies = true;
22752 }
22753
22754 105 Hero.x = (zfix)wx;
22755 105 Hero.y = (zfix)wy;
22756 105 update_viewport();
22757
22758
2/2
✓ Branch 0 taken 75 times.
✓ Branch 1 taken 30 times.
105 switch(heroFacesDir)
22759 {
22760 case up:
22761 case down:
22762 case left:
22763 case right:
22764 75 Hero.dir = heroFacesDir;
22765 75 break;
22766 default:
22767
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if((int32_t)Hero.x==(zfix)0)
22768 {
22769 Hero.dir=right;
22770 }
22771
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if((int32_t)Hero.x==(zfix)240)
22772 {
22773 Hero.dir=left;
22774 }
22775
22776
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if((int32_t)Hero.y==(zfix)0)
22777 {
22778 Hero.dir=down;
22779 }
22780
22781
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if((int32_t)Hero.y==(zfix)160)
22782 {
22783 Hero.dir=up;
22784 }
22785 30 }
22786
22787 105 markBmap(Hero.dir^1, Hero.current_screen);
22788
22789
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 105 times.
105 if(iswaterex_z3(MAPCOMBO((int32_t)Hero.x,(int32_t)Hero.y+8), -1, Hero.x, Hero.y+8, true) && _walkflag((int32_t)Hero.x,(int32_t)Hero.y+8,0) && current_item(itype_flippers))
22790 {
22791 Hero.hopclk=0xFF;
22792 Hero.attackclk = Hero.charging = Hero.spins = 0;
22793 if (isSideViewHero() && get_qr(qr_SIDESWIM)) {Hero.setAction(sideswimming); FFCore.setHeroAction(sideswimming);}
22794 else {Hero.setAction(swimming); FFCore.setHeroAction(swimming);}
22795 }
22796 else
22797 {
22798 105 Hero.setAction(none); FFCore.setHeroAction(none);
22799 }
22800
22801 //preloaded freeform combos
22802 105 ffscript_engine(true);
22803
22804 105 putscr(hero_scr, scrollbuf, 0, 0);
22805 105 putscrdoors(hero_scr, scrollbuf, 0, 0);
22806
22807 105 doWarpEffect(warpEffect, false);
22808 105 show_subscreen_life=true;
22809 105 show_subscreen_numbers=true;
22810
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 101 times.
105 if (!(warpFlags&warpFlagFORCECONTINUEMUSIC)) Play_Level_Music();
22811 105 currcset=DMaps[cur_dmap].color;
22812 105 dointro();
22813 105 Hero.set_respawn_point();
22814 105 Hero.trySideviewLadder();
22815
22816 105 break;
22817 }
22818
22819
22820 case wtEXIT:
22821 {
22822 lighting(false,false,pal_litRESETONLY);//Reset permLit, and do nothing else; lighting was not otherwise called on a wtEXIT warp.
22823 ALLOFF();
22824 if (warpFlags&warpFlagFORCERESETMUSIC) music_stop();
22825 if ( !(warpFlags&warpFlagDONTKILLSOUNDS) ) kill_sfx();
22826 sfx(warpSound);
22827 blackscr(30,false);
22828 bool changedlevel = false;
22829 bool changeddmap = false;
22830 if(cur_dmap != dmap)
22831 {
22832 timeExitAllGenscript(GENSCR_ST_CHANGE_DMAP);
22833 changeddmap = true;
22834 }
22835 if(dlevel != DMaps[dmap].level)
22836 {
22837 timeExitAllGenscript(GENSCR_ST_CHANGE_LEVEL);
22838 changedlevel = true;
22839 }
22840 dlevel = DMaps[dmap].level;
22841 cur_dmap = dmap;
22842 if(changeddmap)
22843 {
22844 throwGenScriptEvent(GENSCR_EVENT_CHANGE_DMAP);
22845 }
22846 if(changedlevel)
22847 {
22848 throwGenScriptEvent(GENSCR_EVENT_CHANGE_LEVEL);
22849 }
22850 cur_map=DMaps[cur_dmap].map;
22851 init_dmap();
22852 update_subscreens(dmap);
22853 loadfullpal();
22854 ringcolor(false);
22855 loadlvlpal(DMaps[cur_dmap].color);
22856 loadscr(cur_dmap, screen + DMaps[cur_dmap].xoff, -1, overlay);
22857
22858 if((hero_scr->flags&fDARK) && !get_qr(qr_NEW_DARKROOM))
22859 {
22860 if(get_qr(qr_FADE))
22861 {
22862 interpolatedfade();
22863 }
22864 else
22865 {
22866 loadfadepal((DMaps[cur_dmap].color)*pdLEVEL+poFADE3);
22867 }
22868
22869 darkroom=naturaldark=true;
22870 }
22871 else
22872 {
22873 darkroom=naturaldark=false;
22874 }
22875
22876
22877 //Move Hero's coordinates
22878 Hero.x = (zfix)wx;
22879 Hero.y = (zfix)wy;
22880 update_viewport();
22881
22882 //set his dir
22883 switch(heroFacesDir)
22884 {
22885 case up:
22886 case down:
22887 case left:
22888 case right:
22889 Hero.dir = heroFacesDir;
22890 break;
22891 default:
22892 Hero.dir=down;
22893 if((int32_t)Hero.x==(zfix)0)
22894 {
22895 Hero.dir=right;
22896 }
22897 if((int32_t)Hero.x==(zfix)240)
22898 {
22899 Hero.dir=left;
22900 }
22901
22902 if((int32_t)Hero.y==(zfix)0)
22903 {
22904 Hero.dir=down;
22905 }
22906
22907 if((int32_t)Hero.y==(zfix)160)
22908 {
22909 Hero.dir=up;
22910 }
22911 }
22912
22913 if(dlevel)
22914 {
22915 // reset enemy kill counts
22916 for(int32_t i=0; i<128; i++)
22917 {
22918 int mi = mapind(cur_map, i);
22919 game->guys[mi] = 0;
22920 game->maps[mi] &= ~mTMPNORET;
22921 }
22922 }
22923
22924 markBmap(Hero.dir^1, Hero.current_screen);
22925 //preloaded freeform combos
22926 ffscript_engine(true);
22927 Hero.reset_hookshot();
22928
22929 if(isdungeon())
22930 {
22931 openscreen();
22932 if(get_er(er_SHORTDGNWALK)==0 && get_qr(qr_SHORTDGNWALK)==0)
22933 Hero.stepforward(Hero.diagonalMovement?11:12, false);
22934 else
22935 // Didn't walk as far pre-1.93, and some quests depend on that
22936 Hero.stepforward(8, false);
22937 }
22938 else
22939 {
22940 openscreen();
22941 }
22942
22943 show_subscreen_life=true;
22944 show_subscreen_numbers=true;
22945 if (!(warpFlags&warpFlagFORCECONTINUEMUSIC))Play_Level_Music();
22946 currcset=DMaps[cur_dmap].color;
22947 dointro();
22948 Hero.set_respawn_point();
22949 Hero.trySideviewLadder();
22950
22951 for(int32_t i=0; i<6; i++)
22952 visited[i]=-1;
22953
22954 //last_entr_scr = scrID;
22955 //last_entr_dmap = dmapID;
22956
22957 break;
22958
22959 }
22960 case wtSCROLL: // scrolling warp
22961 {
22962 10 int32_t c = DMaps[cur_dmap].color;
22963 10 scrolling_dmap = cur_dmap;
22964 10 scrolling_map = cur_map;
22965 10 cur_map = DMaps[dmap].map;
22966 10 update_subscreens(dmap);
22967
22968 10 dlevel = DMaps[dmap].level;
22969 //check if Hero has the map for the new location before updating the subscreen. ? -Z
22970 //This works only in one direction, if Hero had a map, to not having one.
22971 //If Hero does not have a map, and warps somewhere where he does, then the map still briefly shows.
22972 10 update_subscreens(dmap);
22973
22974 // if ( has_item(itype_map, dlevel) )
22975 // {
22976 // //Blank the map during an intra-dmap scrolling warp.
22977 // dlevel = -1; //a hack for the minimap. This works!! -Z
22978 // }
22979
22980 // fix the scrolling direction, if it was a tile or instant warp
22981 10 Hero.sdir = vbound(Hero.dir,0,3);
22982
22983
22984 10 Hero.scrollscr(Hero.sdir, screen+DMaps[dmap].xoff, dmap);
22985 10 bool changedlevel = false;
22986 10 bool changeddmap = false;
22987
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if(cur_dmap != dmap)
22988 {
22989 timeExitAllGenscript(GENSCR_ST_CHANGE_DMAP);
22990 changeddmap = true;
22991 }
22992
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if(dlevel != DMaps[dmap].level)
22993 {
22994 timeExitAllGenscript(GENSCR_ST_CHANGE_LEVEL);
22995 changedlevel = true;
22996 }
22997 10 dlevel = DMaps[dmap].level;
22998 10 cur_dmap = dmap;
22999
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if(changeddmap)
23000 {
23001 throwGenScriptEvent(GENSCR_EVENT_CHANGE_DMAP);
23002 }
23003
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if(changedlevel)
23004 {
23005 throwGenScriptEvent(GENSCR_EVENT_CHANGE_LEVEL);
23006 }
23007
23008 10 Hero.reset_hookshot();
23009
23010
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(!intradmap)
23011 {
23012
5/8
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 10 times.
10 if(((wx>0||wy>0)||(get_qr(qr_WARPSIGNOREARRIVALPOINT)))&&(!get_qr(qr_NOSCROLLCONTINUE))&&(!(hero_scr->flags6&fNOCONTINUEHERE)))
23013 {
23014
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 6 times.
10 if(dlevel)
23015 {
23016 6 lastentrance = cur_screen;
23017 6 }
23018 else
23019 {
23020 4 lastentrance = DMaps[cur_dmap].cont + DMaps[cur_dmap].xoff;
23021 }
23022
23023 10 lastentrance_dmap = dmap;
23024 10 }
23025 10 }
23026
23027
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if(DMaps[cur_dmap].color != c)
23028 {
23029 lighting(false, true);
23030 }
23031
23032
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (!(warpFlags&warpFlagFORCECONTINUEMUSIC)) Play_Level_Music();
23033 10 currcset=DMaps[cur_dmap].color;
23034 10 dointro();
23035 10 break;
23036 }
23037 //Cannot use these types with scripts, or with strings.
23038 case wtCAVE:
23039 case wtPASS:
23040 case wtWHISTLE:
23041 default:
23042 {
23043 Z_scripterrlog("Invalid warp type (%d) supplied to Hero->WarpEx()!. Cannot warp!!\n", warpType);
23044 Hero.is_warping = false;
23045 return false;
23046 }
23047 }
23048 // Stop Hero from drowning!
23049
1/2
✓ Branch 0 taken 115 times.
✗ Branch 1 not taken.
115 if(Hero.getAction()==drowning)
23050 {
23051 Hero.drownclk=0;
23052 Hero.setAction(none); FFCore.setHeroAction(none);
23053 }
23054
23055 // But keep him swimming if he ought to be!
23056
3/8
✓ Branch 0 taken 115 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 115 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 115 times.
✗ Branch 7 not taken.
115 if(Hero.getAction()!=rafting && iswaterex_z3(MAPCOMBO((int32_t)Hero.x,(int32_t)Hero.y+8), -1, Hero.x, Hero.y+8, true) && (_walkflag((int32_t)Hero.x,(int32_t)Hero.y+8,0) || get_qr(qr_DROWN))
23057 && (current_item(itype_flippers)) && (Hero.getAction()!=inwind))
23058 {
23059 Hero.hopclk=0xFF;
23060 if (isSideViewHero() && get_qr(qr_SIDESWIM)) {Hero.setAction(sideswimming); FFCore.setHeroAction(sideswimming);}
23061 else {Hero.setAction(swimming); FFCore.setHeroAction(swimming);}
23062 }
23063
23064 115 newscr_clk=frame;
23065 115 activated_timed_warp=false;
23066 115 eat_buttons();
23067
23068
2/2
✓ Branch 0 taken 82 times.
✓ Branch 1 taken 33 times.
115 if(warpType!=wtIWARP) { Hero.attackclk=0; }
23069
23070 115 Hero.didstuff=0;
23071 115 Hero.usecounts.clear();
23072 115 map_bkgsfx(true);
23073 115 loadside=Hero.dir^1;
23074 115 whistleclk=-1;
23075
23076
2/4
✓ Branch 0 taken 115 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 115 times.
✗ Branch 3 not taken.
115 if(((int32_t)Hero.z>0 || (int32_t)Hero.fakez>0) && isSideViewHero())
23077 {
23078 Hero.y-=Hero.z;
23079 Hero.y-=Hero.fakez;
23080 Hero.z=0;
23081 Hero.fakez=0;
23082 }
23083
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 114 times.
115 else if(!isSideViewHero())
23084 {
23085 114 Hero.fall=0;
23086 114 Hero.fakefall=0;
23087 114 }
23088
23089 // If warping between top-down and sideview screens,
23090 // fix enemies that are carried over by Full Screen Warp
23091 115 const bool tmpscr_is_sideview = isSideViewGravity();
23092
23093
3/4
✓ Branch 0 taken 115 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 114 times.
✓ Branch 3 taken 1 times.
115 if(!wasSideview && tmpscr_is_sideview)
23094 {
23095
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 for(int32_t i=0; i<guys.Count(); i++)
23096 {
23097 if(guys.spr(i)->z > 0)
23098 {
23099 guys.spr(i)->y -= guys.spr(i)->z;
23100 guys.spr(i)->z = 0;
23101 }
23102
23103 if(((enemy*)guys.spr(i))->type!=eeTRAP && ((enemy*)guys.spr(i))->type!=eeSPINTILE)
23104 guys.spr(i)->yofs += 2;
23105 }
23106 1 }
23107
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 114 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
114 else if(wasSideview && !tmpscr_is_sideview)
23108 {
23109 for(int32_t i=0; i<guys.Count(); i++)
23110 {
23111 if(((enemy*)guys.spr(i))->type!=eeTRAP && ((enemy*)guys.spr(i))->type!=eeSPINTILE)
23112 guys.spr(i)->yofs -= 2;
23113 }
23114 }
23115
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 115 times.
115 if ( warpType == wtEXIT )
23116 {
23117 game->set_continue_scrn(cur_screen);
23118 game->set_continue_dmap(dmap);
23119 lastentrance = cur_screen;
23120 lastentrance_dmap = dmap;
23121 }
23122 else
23123 {
23124
2/2
✓ Branch 0 taken 111 times.
✓ Branch 1 taken 4 times.
115 if ( (warpFlags&warpFlagSETENTRANCESCREEN) ) lastentrance = cur_screen;
23125
2/2
✓ Branch 0 taken 111 times.
✓ Branch 1 taken 4 times.
115 if ( (warpFlags&warpFlagSETENTRANCEDMAP) ) lastentrance_dmap = dmap;
23126
2/2
✓ Branch 0 taken 111 times.
✓ Branch 1 taken 4 times.
115 if ( (warpFlags&warpFlagSETCONTINUESCREEN) ) game->set_continue_scrn(cur_screen);
23127
2/2
✓ Branch 0 taken 111 times.
✓ Branch 1 taken 4 times.
115 if ( (warpFlags&warpFlagSETCONTINUEDMAP) ) game->set_continue_dmap(dmap);
23128 }
23129
1/2
✓ Branch 0 taken 115 times.
✗ Branch 1 not taken.
115 if(hero_scr->flags4&fAUTOSAVE)
23130 {
23131 save_game(true,0);
23132 }
23133
23134
2/2
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 2 times.
115 if(hero_scr->flags6&fCONTINUEHERE)
23135 {
23136 2 lastentrance_dmap = cur_dmap;
23137 2 lastentrance = home_screen;
23138 2 }
23139
23140 115 update_subscreens();
23141 115 verifyBothWeapons();
23142 230 Z_eventlog("Warped to DMap %d: %s, screen %d, via %s.\n", cur_dmap, DMaps[cur_dmap].name,cur_screen,
23143
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 115 times.
230 warpType==wtEXIT ? "Entrance/Exit" :
23144
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 105 times.
115 warpType==wtSCROLL ? "Scrolling Warp" :
23145 105 warpType==wtNOWARP ? "Cancel Warp" :
23146 "Insta-Warp");
23147
23148 115 eventlog_mapflags();
23149
4/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 107 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 4 times.
115 if (((warpFlags&warpFlagDONTRESTARTDMAPSCRIPT) != 0) == (get_qr(qr_SCRIPT_WARPS_DMAP_SCRIPT_TOGGLE) != 0)|| olddmap != cur_dmap) //Changed DMaps, or needs to reset the script
23150 {
23151 111 FFScript::deallocateAllScriptOwned(ScriptType::DMap, olddmap);
23152 111 initZScriptDMapScripts();
23153 111 }
23154 115 Hero.is_warping = false;
23155
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 91 times.
115 if(!get_qr(qr_SCROLLWARP_NO_RESET_FRAME))
23156 91 GameFlags |= GAMEFLAG_RESET_GAME_LOOP;
23157 115 return true;
23158 115 }
23159
23160 2004 void FFScript::do_adjustvolume(const bool v)
23161 {
23162
1/2
✓ Branch 0 taken 2004 times.
✗ Branch 1 not taken.
2004 if (get_qr(qr_OLD_SCRIPT_VOLUME))
23163 {
23164 2004 int32_t perc = (SH::get_arg(sarg1, v) / 10000);
23165 2004 float pct = perc / 100.0;
23166 2004 float temp_midi = 0;
23167 2004 float temp_digi = 0;
23168 2004 float temp_mus = 0;
23169
2/2
✓ Branch 0 taken 2000 times.
✓ Branch 1 taken 4 times.
2004 if (!(coreflags & FFCORE_SCRIPTED_MIDI_VOLUME))
23170 {
23171 4 temp_midi = do_getMIDI_volume();
23172 4 usr_midi_volume = do_getMIDI_volume();
23173 4 SetFFEngineFlag(FFCORE_SCRIPTED_MIDI_VOLUME, true);
23174 4 }
23175 else
23176 {
23177 2000 temp_midi = (float)usr_midi_volume;
23178 }
23179
2/2
✓ Branch 0 taken 2000 times.
✓ Branch 1 taken 4 times.
2004 if (!(coreflags & FFCORE_SCRIPTED_DIGI_VOLUME))
23180 {
23181 4 temp_digi = do_getDIGI_volume();
23182 4 usr_digi_volume = do_getDIGI_volume();
23183 4 SetFFEngineFlag(FFCORE_SCRIPTED_DIGI_VOLUME, true);
23184 4 }
23185 else
23186 {
23187 2000 temp_digi = (float)usr_digi_volume;
23188 }
23189
2/2
✓ Branch 0 taken 2000 times.
✓ Branch 1 taken 4 times.
2004 if (!(coreflags & FFCORE_SCRIPTED_MUSIC_VOLUME))
23190 {
23191 4 temp_mus = do_getMusic_volume();
23192 4 usr_music_volume = do_getMusic_volume();
23193 4 SetFFEngineFlag(FFCORE_SCRIPTED_MUSIC_VOLUME, true);
23194 4 }
23195 else
23196 {
23197 2000 temp_mus = (float)usr_music_volume;
23198 }
23199
23200 2004 temp_midi *= pct;
23201 2004 temp_digi *= pct;
23202 2004 temp_mus *= pct;
23203 2004 do_setMIDI_volume((int32_t)temp_midi);
23204 2004 do_setDIGI_volume((int32_t)temp_digi);
23205 2004 do_setMusic_volume((int32_t)temp_mus);
23206 2004 }
23207 else
23208 {
23209 int32_t perc = SH::get_arg(sarg1, v);
23210 FFCore.usr_music_volume = vbound(perc, 0, 10000 * 100);
23211
23212 if (zcmusic != NULL)
23213 {
23214 if (zcmusic->playing != ZCM_STOPPED)
23215 {
23216 int32_t temp_volume = emusic_volume;
23217 if (!get_qr(qr_OLD_SCRIPT_VOLUME))
23218 temp_volume = (emusic_volume * FFCore.usr_music_volume) / 10000 / 100;
23219 temp_volume = (temp_volume * zcmusic->fadevolume) / 10000;
23220 zcmusic_play(zcmusic, temp_volume);
23221 return;
23222 }
23223 }
23224 else if (currmidi > -1)
23225 {
23226 jukebox(currmidi);
23227 master_volume(digi_volume, midi_volume);
23228 }
23229 }
23230 2004 }
23231
23232 void FFScript::do_adjustsfxvolume(const bool v)
23233 {
23234 if (get_qr(qr_OLD_SCRIPT_VOLUME))
23235 {
23236 int32_t perc = (SH::get_arg(sarg1, v) / 10000);
23237 float pct = perc / 100.0;
23238 float temp_sfx = 0;
23239 if (!(coreflags & FFCORE_SCRIPTED_SFX_VOLUME))
23240 {
23241 temp_sfx = do_getSFX_volume();
23242 usr_sfx_volume = (int32_t)temp_sfx;
23243 SetFFEngineFlag(FFCORE_SCRIPTED_SFX_VOLUME, true);
23244 }
23245 else
23246 {
23247 temp_sfx = (float)usr_sfx_volume;
23248 }
23249 temp_sfx *= pct;
23250 do_setSFX_volume((int32_t)temp_sfx);
23251 }
23252 else
23253 {
23254 int32_t perc = SH::get_arg(sarg1, v);
23255 FFCore.usr_sfx_volume = vbound(perc, 0, 10000 * 100);
23256 }
23257 }
23258
23259
23260 63830 void do_midi(bool v)
23261 {
23262 63830 int32_t MIDI = SH::get_arg(sarg1, v) / 10000;
23263
23264
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 63786 times.
63830 if(MIDI == 0)
23265 44 music_stop();
23266 else
23267 63786 jukebox(MIDI + MIDIOFFSET_ZSCRIPT);
23268 63830 }
23269
23270
23271 1 void stop_sfx(const bool v)
23272 {
23273 1 int32_t ID = SH::get_arg(sarg1, v) / 10000;
23274 1 int32_t sfx = (int32_t)ID;
23275
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(BC::checkSFXID(ID) != SH::_NoError)
23276 return;
23277 1 stop_sfx(sfx);
23278 1 }
23279
23280 void pause_sfx(const bool v)
23281 {
23282 int32_t ID = SH::get_arg(sarg1, v) / 10000;
23283 int32_t sfx = (int32_t)ID;
23284 if(BC::checkSFXID(ID) != SH::_NoError)
23285 return;
23286 pause_sfx(sfx);
23287 }
23288
23289 void resume_sfx(const bool v)
23290 {
23291 int32_t ID = SH::get_arg(sarg1, v) / 10000;
23292 int32_t sfx = (int32_t)ID;
23293 if(BC::checkSFXID(ID) != SH::_NoError)
23294 return;
23295 resume_sfx(sfx);
23296 }
23297
23298
23299
23300 357 void do_enh_music(bool v)
23301 {
23302 357 int32_t arrayptr = SH::get_arg(sarg1, v);
23303 357 int32_t track = (SH::get_arg(sarg2, v) / 10000)-1;
23304
23305
2/2
✓ Branch 0 taken 226 times.
✓ Branch 1 taken 131 times.
357 if(arrayptr == 0)
23306 131 music_stop();
23307 else // Pointer to a string..
23308 {
23309 226 string filename_str;
23310 char filename_char[256];
23311 bool ret;
23312
1/2
✓ Branch 0 taken 226 times.
✗ Branch 1 not taken.
226 ArrayH::getString(arrayptr, filename_str, 256);
23313 226 strncpy(filename_char, filename_str.c_str(), 255);
23314 226 filename_char[255]='\0';
23315
2/4
✓ Branch 0 taken 226 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 226 times.
✗ Branch 3 not taken.
226 ret=try_zcmusic(filename_char, qstpath, track, -1000, get_emusic_volume());
23316
1/2
✓ Branch 0 taken 226 times.
✗ Branch 1 not taken.
226 set_register(sarg2, ret ? 10000 : 0);
23317 226 }
23318 357 }
23319
23320 5 void do_enh_music_crossfade()
23321 {
23322 5 int32_t arrayptr = SH::read_stack(ri->sp + 5);
23323 5 int32_t track = SH::read_stack(ri->sp + 4) / 10000;
23324
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 int32_t fadeoutframes = zc_max(SH::read_stack(ri->sp + 3) / 10000, 0);
23325
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 int32_t fadeinframes = zc_max(SH::read_stack(ri->sp + 2) / 10000, 0);
23326 5 int32_t fademiddleframes = SH::read_stack(ri->sp + 1) / 10000;
23327 5 int32_t startpos = SH::read_stack(ri->sp);
23328
23329
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (arrayptr == 0)
23330 {
23331 bool ret = play_enh_music_crossfade(NULL, qstpath, track, get_emusic_volume(), fadeoutframes, fadeinframes, fademiddleframes, startpos);
23332 SET_D(rEXP1, ret ? 10000 : 0);
23333 }
23334 else
23335 {
23336 5 string filename_str;
23337 char filename_char[256];
23338
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 ArrayH::getString(arrayptr, filename_str, 256);
23339 5 strncpy(filename_char, filename_str.c_str(), 255);
23340 5 filename_char[255] = '\0';
23341
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 bool ret = play_enh_music_crossfade(filename_char, qstpath, track, get_emusic_volume(), fadeoutframes, fadeinframes, fademiddleframes, startpos, true);
23342 5 SET_D(rEXP1, ret ? 10000 : 0);
23343 5 }
23344 5 }
23345
23346 bool FFScript::doing_dmap_enh_music(int32_t dm)
23347 {
23348 if (DMaps[dm].tmusic[0] != 0)
23349 {
23350 if (zcmusic != NULL)
23351 {
23352 if (strcmp(zcmusic->filename, DMaps[dm].tmusic) == 0)
23353 {
23354 switch (zcmusic_get_type(zcmusic))
23355 {
23356 case ZCMF_OGG:
23357 case ZCMF_MP3:
23358 return true;
23359 case ZCMF_DUH:
23360 case ZCMF_GME:
23361 if (zcmusic->track == DMaps[dm].tmusictrack)
23362 {
23363 return true;
23364 }
23365 }
23366 }
23367 }
23368 }
23369 return false;
23370 }
23371
23372 40525 bool FFScript::can_dmap_change_music(int32_t dm)
23373 {
23374
1/4
✓ Branch 0 taken 40525 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
40525 switch (music_update_cond)
23375 {
23376 case MUSIC_UPDATE_SCREEN:
23377 40525 return true;
23378 case MUSIC_UPDATE_DMAP:
23379 return dm != -1 && dm != cur_dmap;
23380 case MUSIC_UPDATE_LEVEL:
23381 return dm != -1 && DMaps[dm].level != DMaps[cur_dmap].level;
23382 }
23383 return false;
23384 40525 }
23385
23386 void FFScript::do_set_music_position(const bool v)
23387 {
23388 int32_t newposition = SH::get_arg(sarg1, v);
23389
23390 set_zcmusicpos(newposition);
23391 }
23392
23393 void FFScript::do_get_music_position()
23394 {
23395 int32_t pos = replay_get_state(ReplayStateType::MusicPosition, [](){
23396 return zcmusic_get_curpos(zcmusic);
23397 });
23398 set_register(sarg1, pos);
23399 }
23400
23401 void FFScript::do_set_music_speed(const bool v)
23402 {
23403 int32_t newspeed = SH::get_arg(sarg1, v);
23404 set_zcmusicspeed(newspeed);
23405 }
23406
23407 void FFScript::do_get_music_length()
23408 {
23409 int32_t len = get_zcmusiclen();
23410 set_register(sarg1, len);
23411 }
23412
23413 3 void FFScript::do_set_music_loop()
23414 {
23415 3 double start = (get_register(sarg1) / 10000.0);
23416 3 double end = (get_register(sarg2) / 10000.0);
23417
23418 3 set_zcmusicloop(start, end);
23419 3 }
23420
23421 236 void do_get_enh_music_filename(const bool v)
23422 {
23423 236 int32_t ID = SH::get_arg(sarg1, v) / 10000;
23424 236 int32_t arrayptr = get_register(sarg2);
23425
23426
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 236 times.
236 if(BC::checkDMapID(ID) != SH::_NoError)
23427 return;
23428
23429
3/6
✓ Branch 0 taken 236 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 236 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 236 times.
✗ Branch 5 not taken.
236 if(ArrayH::setArray(arrayptr, string(DMaps[ID].tmusic)) == SH::_Overflow)
23430 Z_scripterrlog("Array supplied to 'Game->GetDMapMusicFilename' not large enough\n");
23431 236 }
23432
23433 140 void do_get_enh_music_track(const bool v)
23434 {
23435 140 int32_t ID = SH::get_arg(sarg1, v) / 10000;
23436
23437
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 132 times.
140 if(BC::checkDMapID(ID) != SH::_NoError)
23438 8 return;
23439
23440 132 set_register(sarg1, (DMaps[ID].tmusictrack+1)*10000);
23441 140 }
23442
23443 3807 void do_set_dmap_enh_music(const bool v)
23444 {
23445 3807 int32_t ID = SH::read_stack(ri->sp + 2) / 10000;
23446 3807 int32_t arrayptr = SH::read_stack(ri->sp + 1);
23447 3807 int32_t track = (SH::read_stack(ri->sp + 0) / 10000)-1;
23448 3807 string filename_str;
23449
23450
2/4
✓ Branch 0 taken 3807 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3807 times.
✗ Branch 3 not taken.
3807 if(BC::checkDMapID(ID) != SH::_NoError)
23451 return;
23452
23453
1/2
✓ Branch 0 taken 3807 times.
✗ Branch 1 not taken.
3807 ArrayH::getString(arrayptr, filename_str, 56);
23454 3807 strncpy(DMaps[ID].tmusic, filename_str.c_str(), 55);
23455 3807 DMaps[ID].tmusic[55]='\0';
23456 3807 DMaps[ID].tmusictrack=track;
23457
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3807 times.
3807 }
23458
23459
23460
23461
23462
23463
23464 ///----------------------------------------------------------------------------------------------------//
23465 //Array & string related
23466
23467 303089179 void do_arraysize()
23468 {
23469 303089179 int32_t arrayptr = get_register(sarg1);
23470 303089179 SET_D(rEXP1, ArrayH::getSize(arrayptr) * 10000);
23471 303089179 }
23472
23473 void do_tobyte()
23474 {
23475 int32_t b1 = get_register(sarg1) / 10000;
23476 byte b2 = b1;
23477 set_register(sarg1, b2 * 10000);
23478 }
23479
23480 void do_tosignedbyte()
23481 {
23482 int32_t b1 = get_register(sarg1) / 10000;
23483 signed char b2 = b1;
23484 set_register(sarg1, b2 * 10000);
23485 }
23486
23487 void do_tointeger()
23488 {
23489 int32_t b1 = get_register(sarg1) / 10000;
23490 set_register(sarg1, b1 * 10000);
23491 }
23492
23493 void do_floor()
23494 {
23495 set_register(sarg1, zslongToFix(get_register(sarg1)).doFloor().getZLong());
23496 }
23497
23498 void do_trunc()
23499 {
23500 set_register(sarg1, zslongToFix(get_register(sarg1)).doTrunc().getZLong());
23501 }
23502
23503 void do_ceiling()
23504 {
23505 set_register(sarg1, zslongToFix(get_register(sarg1)).doCeil().getZLong());
23506 }
23507
23508 void do_round()
23509 {
23510 set_register(sarg1, zslongToFix(get_register(sarg1)).doRound().getZLong());
23511 }
23512
23513 void do_roundaway()
23514 {
23515 set_register(sarg1, zslongToFix(get_register(sarg1)).doRoundAway().getZLong());
23516 }
23517
23518 void do_toword()
23519 {
23520 int32_t b1 = get_register(sarg1) / 10000;
23521 word b2 = b1;
23522 set_register(sarg1, b2 * 10000);
23523 }
23524
23525 void do_toshort()
23526 {
23527 int32_t b1 = get_register(sarg1) / 10000;
23528 int16_t b2 = b1;
23529 set_register(sarg1, b2 * 10000);
23530 }
23531
23532 //Set npc and item names t.b.a. -Z
23533
23534 2768 void do_getitemname()
23535 {
23536 2768 int32_t arrayptr = get_register(sarg1);
23537
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2768 times.
2768 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
23538 {
23539 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
23540 return;
23541 }
23542
23543
3/6
✓ Branch 0 taken 2768 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2768 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2768 times.
✗ Branch 5 not taken.
2768 if(ArrayH::setArray(arrayptr, item_string[GET_REF(itemdataref)]) == SH::_Overflow)
23544 Z_scripterrlog("Array supplied to 'itemdata->GetName' not large enough\n");
23545 2768 }
23546
23547 10105657 void do_getffcscript()
23548 {
23549 10105657 do_get_script_index_by_name(name_to_slot_index_ffcmap);
23550 10105657 }
23551
23552 80 void do_getitemscript()
23553 {
23554 80 do_get_script_index_by_name(name_to_slot_index_itemmap);
23555 80 }
23556
23557 ///----------------------------------------------------------------------------------------------------//
23558 //Tile Manipulation
23559
23560 49289145 void do_copytile(const bool v, const bool v2)
23561 {
23562 49289145 int32_t tile = SH::get_arg(sarg1, v) / 10000;
23563 49289145 int32_t tile2 = SH::get_arg(sarg2, v2) / 10000;
23564
23565 49289145 copy_tile(newtilebuf, tile, tile2, false);
23566 49289145 }
23567
23568 int32_t FFScript::IsBlankTile(int32_t i)
23569 {
23570 if( ((unsigned)i) > NEWMAXTILES )
23571 {
23572 scripting_log_error_with_context("Invalid tile ID {}", i);
23573 return -1;
23574 }
23575
23576 byte *tilestart=newtilebuf[i].data;
23577 qword *di=(qword*)tilestart;
23578 int32_t parts=tilesize(newtilebuf[i].format)>>3;
23579
23580 for(int32_t j=0; j<parts; ++j, ++di)
23581 {
23582 if(*di!=0)
23583 {
23584 return 0;
23585 }
23586 }
23587
23588 return 1;
23589 }
23590
23591 int32_t FFScript::Is8BitTile(int32_t i)
23592 {
23593 if (((unsigned)i) > NEWMAXTILES)
23594 {
23595 scripting_log_error_with_context("Invalid tile ID {}", i);
23596 return -1;
23597 }
23598
23599 return newtilebuf[i].format == tf8Bit ? 1 : 0;
23600 }
23601
23602 void do_swaptile(const bool v, const bool v2)
23603 {
23604 int32_t tile = SH::get_arg(sarg1, v) / 10000;
23605 int32_t tile2 = SH::get_arg(sarg2, v2) / 10000;
23606
23607 copy_tile(newtilebuf, tile, tile2, true);
23608 }
23609
23610 57032 void do_overlaytile(const bool v, const bool v2)
23611 {
23612 57032 int32_t tile = SH::get_arg(sarg1, v) / 10000;
23613 57032 int32_t tile2 = SH::get_arg(sarg2, v2) / 10000;
23614
23615
2/4
✓ Branch 0 taken 57032 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 57032 times.
✗ Branch 3 not taken.
57032 if(BC::checkTile(tile) != SH::_NoError ||
23616 57032 BC::checkTile(tile2) != SH::_NoError)
23617 return;
23618
23619 //Could add an arg for the CSet or something instead of just passing 0, currently only 8-bit is supported
23620 57032 overlay_tile(newtilebuf, tile, tile2, 0, false);
23621 57032 }
23622
23623 void do_fliprotatetile(const bool v, const bool v2)
23624 {
23625 int32_t tile = SH::get_arg(sarg1, v) / 10000;
23626 int32_t tile2 = SH::get_arg(sarg2, v2) / 10000;
23627
23628 if(BC::checkTile(tile) != SH::_NoError ||
23629 BC::checkTile(tile2) != SH::_NoError)
23630 return;
23631
23632 //fliprotatetile
23633 }
23634
23635 void do_settilepixel()
23636 {
23637 int32_t tile = SH::read_stack(ri->sp + 3) / 10000;
23638 int32_t x = SH::read_stack(ri->sp + 2) / 10000;
23639 int32_t y = SH::read_stack(ri->sp + 1) / 10000;
23640 int32_t val = SH::read_stack(ri->sp + 0) / 10000;
23641
23642 if(BC::checkTile(tile) != SH::_NoError)
23643 return;
23644
23645 x = vbound(x, 0, 15);
23646 y = vbound(y, 0, 15);
23647 unpack_tile(newtilebuf, tile, 0, false);
23648 if (newtilebuf[tile].format == tf4Bit)
23649 val &= 0xF;
23650 unpackbuf[y * 16 + x] = val;
23651 pack_tile(newtilebuf, unpackbuf, tile);
23652 }
23653
23654 void do_gettilepixel()
23655 {
23656 int32_t tile = SH::read_stack(ri->sp + 3) / 10000;
23657 int32_t x = SH::read_stack(ri->sp + 2) / 10000;
23658 int32_t y = SH::read_stack(ri->sp + 1) / 10000;
23659 int32_t cs = SH::read_stack(ri->sp + 0) / 10000;
23660
23661 if(BC::checkTile(tile) != SH::_NoError)
23662 return;
23663
23664 x = vbound(x, 0, 15);
23665 y = vbound(y, 0, 15);
23666 unpack_tile(newtilebuf, tile, 0, false);
23667 int32_t csoffs = newtilebuf[tile].format == tf8Bit ? 0 : cs * 16;
23668 SET_D(rEXP1, 10000 * (unpackbuf[y * 16 + x] + csoffs));
23669 }
23670
23671 void do_shifttile(const bool v, const bool v2)
23672 {
23673 int32_t tile = SH::get_arg(sarg1, v) / 10000;
23674 int32_t tile2 = SH::get_arg(sarg2, v2) / 10000;
23675
23676 if(BC::checkTile(tile) != SH::_NoError ||
23677 BC::checkTile(tile2) != SH::_NoError)
23678 return;
23679
23680 //shifttile
23681 }
23682
23683 10 void do_cleartile(const bool v)
23684 {
23685 10 int32_t tile = SH::get_arg(sarg1, v) / 10000;
23686
23687
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(BC::checkTile(tile) != SH::_NoError)
23688 return;
23689
23690 10 reset_tile(newtilebuf, tile, newtilebuf[tile].format);
23691 10 }
23692
23693 3182 void do_combotile(const bool v)
23694 {
23695 3182 int32_t combo = SH::get_arg(sarg2, v) / 10000;
23696
23697
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3182 times.
3182 if(BC::checkCombo(combo) != SH::_NoError)
23698 return;
23699
23700 3182 set_register(sarg1, combobuf[combo].tile * 10000);
23701 3182 }
23702
23703 316528283 void do_readpod(const bool v)
23704 {
23705 316528283 int32_t indx = SH::get_arg(sarg2, v) / 10000;
23706 316528283 int32_t val = ArrayH::getElement(GET_D(rINDEX), indx, can_neg_array);
23707 316528283 set_register(sarg1, val);
23708 316528283 }
23709 144937539 void do_writepod(const bool v1, const bool v2)
23710 {
23711 144937539 int32_t indx = SH::get_arg(sarg1, v1) / 10000;
23712 144937539 int32_t val = SH::get_arg(sarg2, v2);
23713 144937539 auto type = (script_object_type)sarg3;
23714 144937539 ArrayH::setElement(GET_D(rINDEX), indx, val, can_neg_array, type);
23715 144937539 }
23716 3274214 void do_writepodstr()
23717 {
23718
2/2
✓ Branch 0 taken 30329 times.
✓ Branch 1 taken 3243885 times.
3274214 if(!sargstr) return;
23719 3243885 uint32_t id = get_register(sarg1);
23720 3243885 ArrayH::setArray(id, *sargstr);
23721 3274214 }
23722 569832 void do_writepodarr()
23723 {
23724
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 569832 times.
569832 if(!sargvec) return;
23725
23726 569832 uint32_t id = get_register(sarg1);
23727 569832 ArrayH::setArray(id, sargvec->size(), sargvec->data(), false);
23728 569832 }
23729
23730 3960 sprite* get_own_sprite(ScriptType type)
23731 {
23732
2/7
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3935 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
3960 switch(type)
23733 {
23734 case ScriptType::None:
23735 25 return ResolveBaseSprite(GET_REF(spriteref));
23736 case ScriptType::Lwpn:
23737 return checkLWpn(GET_REF(lwpnref));
23738 case ScriptType::Ewpn:
23739 return checkEWpn(GET_REF(ewpnref));
23740 case ScriptType::ItemSprite:
23741 return checkItem(GET_REF(itemref));
23742 case ScriptType::NPC:
23743 3935 return checkNPC(GET_REF(npcref));
23744 case ScriptType::FFC:
23745 return ResolveFFC(GET_REF(ffcref));
23746 }
23747 return nullptr;
23748 3960 }
23749
23750 portal* loadportal(savedportal& p);
23751
23752 ///----------------------------------------------------------------------------------------------------//
23753 // Run the script //
23754 ///----------------------------------------------------------------------------------------------------//
23755
23756 11138890 static bool check_cmp(uint cmp)
23757 {
23758
2/2
✓ Branch 0 taken 5519 times.
✓ Branch 1 taken 11133371 times.
11138890 if(cmp & CMP_BOOL)
23759 {
23760
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5519 times.
5519 if(ri->cmp_strcache) return false; //Cast string to bool? nonsense...
23761
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 5519 times.
5519 switch(cmp & CMP_FLAGS)
23762 {
23763 case CMP_EQ:
23764 return !ri->cmp_op1 == !ri->cmp_op2;
23765 case CMP_NE:
23766 5519 return !ri->cmp_op1 != !ri->cmp_op2;
23767 }
23768 return false;
23769 }
23770
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11133371 times.
11133371 else if(ri->cmp_strcache)
23771 {
23772 if(*ri->cmp_strcache < 0)
23773 return (cmp & CMP_LT);
23774 if(*ri->cmp_strcache > 0)
23775 return (cmp & CMP_GT);
23776 return (cmp & CMP_EQ);
23777 }
23778 else
23779 {
23780
2/2
✓ Branch 0 taken 2715395 times.
✓ Branch 1 taken 8417976 times.
11133371 if(cmp & CMP_GT)
23781
2/2
✓ Branch 0 taken 2420078 times.
✓ Branch 1 taken 5997898 times.
8417976 if(ri->cmp_op1 > ri->cmp_op2)
23782 2420078 return true;
23783
2/2
✓ Branch 0 taken 6066482 times.
✓ Branch 1 taken 2646811 times.
8713293 if(cmp & CMP_LT)
23784
2/2
✓ Branch 0 taken 1766996 times.
✓ Branch 1 taken 879815 times.
2646811 if(ri->cmp_op1 < ri->cmp_op2)
23785 1766996 return true;
23786
2/2
✓ Branch 0 taken 2831760 times.
✓ Branch 1 taken 4114537 times.
6946297 if(cmp & CMP_EQ)
23787
2/2
✓ Branch 0 taken 991975 times.
✓ Branch 1 taken 3122562 times.
4114537 if(ri->cmp_op1 == ri->cmp_op2)
23788 991975 return true;
23789 5954322 return false;
23790 }
23791 11138890 }
23792
23793 7579 static void markRegisterType(int reg, int type)
23794 {
23795 // Currently only marking globals as objects is supported.
23796
1/2
✓ Branch 0 taken 7579 times.
✗ Branch 1 not taken.
7579 if (!(reg >= GD(0) && reg <= GD(MAX_SCRIPT_REGISTERS)))
23797 {
23798 assert(false);
23799 }
23800
1/2
✓ Branch 0 taken 7579 times.
✗ Branch 1 not taken.
7579 if (!(type >= 0 && type <= (int)script_object_type::last))
23801 {
23802 assert(false);
23803 }
23804
23805 7579 int index = reg - GD(0);
23806 7579 game->global_d_types[index] = (script_object_type)type;
23807 7579 }
23808
23809 1154 static void markGlobalRegisters()
23810 {
23811 word scommand;
23812 1154 auto& init_script = *globalscripts[GLOBAL_SCRIPT_INIT];
23813
2/2
✓ Branch 0 taken 687 times.
✓ Branch 1 taken 467 times.
1154 if (!init_script.valid())
23814 467 return;
23815
23816 687 auto& zasm = init_script.zasm_script->zasm;
23817 687 uint32_t start_pc = init_script.pc, end_pc = init_script.end_pc;
23818
23819
2/2
✓ Branch 0 taken 687 times.
✓ Branch 1 taken 527804 times.
528491 for (auto pc = start_pc; pc < end_pc; pc++)
23820 {
23821 527804 scommand = zasm[pc].command;
23822
2/2
✓ Branch 0 taken 523443 times.
✓ Branch 1 taken 4361 times.
527804 if(scommand == MARK_TYPE_REG)
23823 4361 markRegisterType(zasm[pc].arg1, zasm[pc].arg2);
23824 527804 }
23825 1154 }
23826
23827 void goto_err(char const* opname)
23828 {
23829 auto i = curScriptIndex;
23830 const char* type_str = ScriptTypeToString(curScriptType);
23831 switch(curScriptType)
23832 {
23833 case ScriptType::FFC:
23834 Z_scripterrlog("%s Script %s attempted to %s an invalid jump to (%d).\n", type_str, ffcmap[i].scriptname.c_str(), opname, sarg1); break;
23835 case ScriptType::NPC:
23836 Z_scripterrlog("%s Script %s attempted to %s an invalid jump to (%d).\n", type_str, npcmap[i].scriptname.c_str(), opname, sarg1); break;
23837 case ScriptType::Lwpn:
23838 Z_scripterrlog("%s Script %s attempted to %s an invalid jump to (%d).\n", type_str, lwpnmap[i].scriptname.c_str(), opname, sarg1); break;
23839 case ScriptType::Ewpn:
23840 Z_scripterrlog("%s Script %s attempted to %s an invalid jump to (%d).\n", type_str, ewpnmap[i].scriptname.c_str(), opname, sarg1); break;
23841 case ScriptType::ItemSprite:
23842 Z_scripterrlog("%s Script %s attempted to %s an invalid jump to (%d).\n", type_str, itemspritemap[i].scriptname.c_str(), opname, sarg1); break;
23843 case ScriptType::Item:
23844 Z_scripterrlog("%s Script %s attempted to %s an invalid jump to (%d).\n", type_str, itemmap[i].scriptname.c_str(), opname, sarg1); break;
23845 case ScriptType::Global:
23846 Z_scripterrlog("%s Script %s attempted to %s an invalid jump to (%d).\n", type_str, globalmap[i].scriptname.c_str(), opname, sarg1); break;
23847 case ScriptType::Hero:
23848 Z_scripterrlog("%s Script %s attempted to %s an invalid jump to (%d).\n", type_str, playermap[i].scriptname.c_str(), opname, sarg1); break;
23849 case ScriptType::Screen:
23850 Z_scripterrlog("%s Script %s attempted to %s an invalid jump to (%d).\n", type_str, screenmap[i].scriptname.c_str(), opname, sarg1); break;
23851 case ScriptType::OnMap:
23852 case ScriptType::DMap:
23853 case ScriptType::ScriptedActiveSubscreen:
23854 case ScriptType::ScriptedPassiveSubscreen:
23855 Z_scripterrlog("%s Script %s attempted to %s an invalid jump to (%d).\n", type_str, dmapmap[i].scriptname.c_str(), opname, sarg1); break;
23856 case ScriptType::Combo:
23857 Z_scripterrlog("%s Script %s attempted to %s an invalid jump to (%d).\n", type_str, comboscriptmap[i].scriptname.c_str(), opname, sarg1); break;
23858
23859 default: break;
23860 }
23861 }
23862
23863 95252 static void script_exit_cleanup(bool no_dealloc)
23864 {
23865 95252 ScriptType type = curScriptType;
23866 95252 word script = curScriptNum;
23867 95252 int32_t i = curScriptIndex;
23868
23869
7/8
✓ Branch 0 taken 17133 times.
✓ Branch 1 taken 64858 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11015 times.
✓ Branch 4 taken 106 times.
✓ Branch 5 taken 51 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 2079 times.
95252 switch(type)
23870 {
23871 case ScriptType::FFC:
23872 {
23873
1/2
✓ Branch 0 taken 11015 times.
✗ Branch 1 not taken.
11015 if (auto ffc = ResolveFFCWithID(i))
23874 11015 ffc->script = 0;
23875 11015 auto& data = get_script_engine_data(type, i);
23876 11015 data.doscript = false;
23877 11015 data.clear_ref();
23878 }
23879 11015 break;
23880
23881 case ScriptType::Screen:
23882 106 get_scr(i)->script = 0;
23883 case ScriptType::Global:
23884 case ScriptType::Hero:
23885 case ScriptType::DMap:
23886 case ScriptType::OnMap:
23887 case ScriptType::ScriptedActiveSubscreen:
23888 case ScriptType::ScriptedPassiveSubscreen:
23889 case ScriptType::EngineSubscreen:
23890 case ScriptType::Combo:
23891 {
23892 17239 auto& data = get_script_engine_data(type, i);
23893 17239 data.doscript = false;
23894 17239 data.clear_ref();
23895 }
23896 17239 break;
23897 case ScriptType::Ewpn:
23898 case ScriptType::Lwpn:
23899 case ScriptType::NPC:
23900 case ScriptType::ItemSprite:
23901 {
23902 64858 auto& data = get_script_engine_data(type, i);
23903 64858 data.doscript = false;
23904 64858 data.clear_ref();
23905
1/2
✓ Branch 0 taken 64858 times.
✗ Branch 1 not taken.
64858 if (auto spr = sprite::getByUID(i))
23906 64858 spr->script = 0;
23907 }
23908 64858 break;
23909
23910 case ScriptType::Generic:
23911 51 user_genscript::get(script).quit();
23912 51 break;
23913
23914 case ScriptType::GenericFrozen:
23915 {
23916 // TODO use `i`?
23917 10 auto& data = get_script_engine_data(type, gen_frozen_index-1);
23918 10 data.doscript = false;
23919 10 data.clear_ref();
23920 10 break;
23921 }
23922
23923 case ScriptType::Item:
23924 {
23925
2/2
✓ Branch 0 taken 1742 times.
✓ Branch 1 taken 337 times.
2079 bool collect = ( ( i < 1 ) || (i == COLLECT_SCRIPT_ITEM_ZERO) );
23926 2079 auto& data = get_script_engine_data(type, i);
23927
2/2
✓ Branch 0 taken 337 times.
✓ Branch 1 taken 1742 times.
2079 if ( !collect )
23928 {
23929
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1742 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1742 if ( (itemsbuf[i].flags&item_passive_script) && game->item[i] ) itemsbuf[i].script = 0; //Quit perpetual scripts, too.
23930 1742 }
23931 2079 data.doscript = 0;
23932 2079 data.clear_ref();
23933 2079 break;
23934 }
23935 }
23936
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 95252 times.
95252 if(!no_dealloc)
23937
2/2
✓ Branch 0 taken 93173 times.
✓ Branch 1 taken 2079 times.
95252 switch(type)
23938 {
23939 case ScriptType::Item:
23940 {
23941
2/2
✓ Branch 0 taken 1742 times.
✓ Branch 1 taken 337 times.
2079 bool collect = ( ( i < 1 ) || (i == COLLECT_SCRIPT_ITEM_ZERO) );
23942
3/4
✓ Branch 0 taken 337 times.
✓ Branch 1 taken 1742 times.
✓ Branch 2 taken 337 times.
✗ Branch 3 not taken.
2079 int new_i = ( collect ) ? (( i != COLLECT_SCRIPT_ITEM_ZERO ) ? (i * -1) : 0) : i;
23943 2079 FFScript::deallocateAllScriptOwned(type, new_i);
23944 2079 break;
23945 }
23946
23947 default:
23948 93173 FFScript::deallocateAllScriptOwned(type, i);
23949 93173 break;
23950 95252 }
23951 95252 }
23952
23953 39186226 int32_t run_script(ScriptType type, word script, int32_t i)
23954 {
23955
3/4
✓ Branch 0 taken 39186226 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 108 times.
✓ Branch 3 taken 39186118 times.
39186226 if(Quit==qRESET || Quit==qEXIT) // In case an earlier script hung
23956 108 return RUNSCRIPT_ERROR;
23957
23958
4/4
✓ Branch 0 taken 26861809 times.
✓ Branch 1 taken 12324309 times.
✓ Branch 2 taken 4459670 times.
✓ Branch 3 taken 22402139 times.
39186118 if(type != ScriptType::Global && !script) return RUNSCRIPT_OK; //Safeguard against running null scripts
23959
23960 34726448 combopos_modified = -1;
23961 34726448 curScriptType=type;
23962 34726448 curScriptNum=script;
23963 34726448 curScriptIndex=i;
23964 34726448 current_zasm_register=0;
23965 //numInstructions=0; //DON'T CLEAR THIS OR IT CAN HARDLOCK! -Em
23966
23967
2/4
✓ Branch 0 taken 34726448 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 34726448 times.
34726448 if (!(type >= ScriptType::First && type <= ScriptType::Last))
23968 {
23969 al_trace("Invalid script type: %d\n", (int)type);
23970 return RUNSCRIPT_ERROR;
23971 }
23972
23973 34726448 auto& data = get_script_engine_data(type, i);
23974 34726448 set_current_script_engine_data(data, type, script, i);
23975
23976 // Because qst.cpp likes to write script_data without setting this.
23977 34726448 curscript->meta.script_type = type;
23978
23979 // If script isn't valid, we don't have a `pc` to start from... just exit.
23980
2/2
✓ Branch 0 taken 34723550 times.
✓ Branch 1 taken 2898 times.
34726448 if(!curscript->valid())
23981 {
23982 2898 script_exit_cleanup(false);
23983 2898 return RUNSCRIPT_OK;
23984 }
23985
23986 34723550 script_funcrun = false;
23987
23988 34723550 JittedScriptInstance* j_instance = nullptr;
23989
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34723550 times.
34723550 if (jit_is_enabled())
23990 {
23991 34723550 auto& data = get_script_engine_data(type, i);
23992
2/2
✓ Branch 0 taken 34599386 times.
✓ Branch 1 taken 124164 times.
34723550 if (!data.j_instance)
23993 124164 data.j_instance = std::shared_ptr<JittedScriptInstance>(jit_create_script_instance(curscript, ri));
23994 34723550 j_instance = data.j_instance.get();
23995 34723550 }
23996
23997 34723550 runtime_script_debug_handle = nullptr;
23998
1/2
✓ Branch 0 taken 34723550 times.
✗ Branch 1 not taken.
34723550 if (script_debug_is_runtime_debugging())
23999 {
24000 if (!script_debug_handles.contains(curscript->id))
24001 {
24002 script_debug_handles.emplace(curscript->id, ScriptDebugHandle(
24003 curscript->zasm_script.get(), ScriptDebugHandle::OutputSplit::ByFrame, curscript->name()));
24004 }
24005 runtime_script_debug_handle = &script_debug_handles.at(curscript->id);
24006 runtime_script_debug_handle->update_file();
24007 std::string line = fmt::format("=== running script type: {} index: {} name: {} i: {} script: {}", ScriptTypeToString(curscript->id.type), curscript->id.index, curscript->meta.script_name, i, script);
24008 runtime_script_debug_handle->print("\n");
24009 runtime_script_debug_handle->print(line.c_str());
24010 runtime_script_debug_handle->print("\n");
24011
24012 replay_step_comment(line);
24013 }
24014
1/2
✓ Branch 0 taken 34723550 times.
✗ Branch 1 not taken.
34723550 if (script_debug_is_runtime_debugging() == 1)
24015 {
24016 std::string line = script_debug_registers_and_stack_to_string();
24017 runtime_script_debug_handle->print(line.c_str());
24018 runtime_script_debug_handle->print("\n");
24019
24020 util::replchar(line, '\n', ' ');
24021 replay_step_comment(line);
24022 }
24023
24024 int32_t result;
24025
2/2
✓ Branch 0 taken 34722329 times.
✓ Branch 1 taken 1221 times.
34723550 if (j_instance)
24026 {
24027
2/2
✓ Branch 0 taken 70511 times.
✓ Branch 1 taken 34651818 times.
34722329 if (ri->waitframes)
24028 {
24029 70511 --ri->waitframes;
24030 70511 result = RUNSCRIPT_OK;
24031 70511 }
24032 else
24033 {
24034 // Retain the script instance because if deleted while running, terrible things can happen (crash),
24035 // as the jit runtimes often write to it. Typically a script won't delete its own script handle,
24036 // but scripts can run nested, so lets capture a temporary retaining reference as part of the
24037 // call stack.
24038 34651818 auto retainer = data.j_instance;
24039
1/2
✓ Branch 0 taken 34651818 times.
✗ Branch 1 not taken.
34651818 result = jit_run_script(j_instance);
24040
24041
4/4
✓ Branch 0 taken 34651816 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 34651814 times.
34651818 if (result == RUNSCRIPT_JIT_STACK_OVERFLOW || result == RUNSCRIPT_JIT_CALL_LIMIT)
24042 {
24043 4 ri->overflow = true;
24044
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (result == RUNSCRIPT_JIT_STACK_OVERFLOW)
24045
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 log_stack_overflow_error();
24046 else
24047
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 log_call_limit_error();
24048
24049
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 if (!(script_funcrun && curscript->meta.ffscript_v < 23))
24050 {
24051
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 script_exit_cleanup(false);
24052 4 result = RUNSCRIPT_STOPPED;
24053 4 }
24054 else
24055 {
24056 result = RUNSCRIPT_OK;
24057 }
24058 4 }
24059 34651818 }
24060 34722329 }
24061 else
24062 {
24063 1221 result = run_script_int();
24064 }
24065
24066
2/2
✓ Branch 0 taken 24326322 times.
✓ Branch 1 taken 10397228 times.
34723550 if (ZScriptVersion::gc())
24067 {
24068 // Drain the autorelease pool.
24069 // Move the vector, since destructors can possibly
24070 // create objects and modify `script_object_autorelease_pool`.
24071 10397228 auto ids = std::move(script_object_autorelease_pool);
24072
2/2
✓ Branch 0 taken 10397228 times.
✓ Branch 1 taken 53441 times.
10450669 for (auto id : ids)
24073
1/2
✓ Branch 0 taken 53441 times.
✗ Branch 1 not taken.
53441 script_object_ref_dec(id);
24074
24075 // This throttles the actual full GC run.
24076
1/2
✓ Branch 0 taken 10397228 times.
✗ Branch 1 not taken.
10397228 maybe_run_gc();
24077 10397228 }
24078
24079
6/16
✗ Branch 0 not taken.
✓ Branch 1 taken 34723550 times.
✓ Branch 2 taken 34723550 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 34723550 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 34723550 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 34723550 times.
✓ Branch 10 taken 34723550 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
69447100 if (replay_is_active() && replay_get_meta_bool("debug_script_state"))
24080 {
24081 std::string str = script_debug_registers_and_stack_to_string();
24082 util::replstr(str, "\n", " ");
24083 replay_step_comment(str);
24084 }
24085
24086
1/2
✓ Branch 0 taken 34723550 times.
✗ Branch 1 not taken.
34723550 if (runtime_script_debug_handle)
24087 {
24088 runtime_script_debug_handle->print(fmt::format("result: {}\n", result).c_str());
24089 replay_step_comment(fmt::format("result: {}", result));
24090 }
24091 34723550 return result;
24092 39186226 }
24093
24094 // Run [count] number of commands (unless something errors).
24095 7439178 int32_t run_script_jit_sequence(JittedScriptInstance* j_instance, int32_t pc, uint32_t sp, int32_t count)
24096 {
24097 7439178 ri->pc = pc;
24098 7439178 ri->sp = sp;
24099 7439178 j_instance->uncompiled_command_count = count;
24100 7439178 j_instance->sequence_mode = true;
24101 7439178 j_instance->should_wait = false;
24102 7439178 int r = run_script_int(j_instance);
24103
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 7439167 times.
7439178 if (r != RUNSCRIPT_OK)
24104 11 return r;
24105
24106 7439167 return j_instance->should_wait ? RUNSCRIPT_STOPPED : RUNSCRIPT_OK;
24107 7439178 }
24108
24109 // Run a single command.
24110 1361926071 int32_t run_script_jit_one(JittedScriptInstance* j_instance, int32_t pc, uint32_t sp)
24111 {
24112 1361926071 ri->pc = pc;
24113 1361926071 ri->sp = sp;
24114 1361926071 j_instance->uncompiled_command_count = 1;
24115 1361926071 j_instance->sequence_mode = true;
24116 1361926071 j_instance->should_wait = false;
24117 1361926071 int r = run_script_int(j_instance);
24118
2/2
✓ Branch 0 taken 95653 times.
✓ Branch 1 taken 1361830418 times.
1361926071 if (r != RUNSCRIPT_OK)
24119 95653 return r;
24120
24121 1361830418 return j_instance->should_wait ? RUNSCRIPT_STOPPED : RUNSCRIPT_OK;
24122 1361926071 }
24123
24124 // Runs the script until the next function call, return, wait frame, or error.
24125 1399085 int32_t run_script_jit_until_call_or_return(JittedScriptInstance* j_instance, int32_t pc, uint32_t sp)
24126 {
24127 1399085 ri->pc = pc;
24128 1399085 ri->sp = sp;
24129 1399085 j_instance->uncompiled_command_count = -1;
24130 1399085 j_instance->sequence_mode = false;
24131 1399085 j_instance->should_wait = false;
24132 1399085 int r = run_script_int(j_instance);
24133
2/2
✓ Branch 0 taken 636 times.
✓ Branch 1 taken 1398449 times.
1399085 if (r != RUNSCRIPT_OK)
24134 636 return r;
24135
24136 1398449 return j_instance->should_wait ? RUNSCRIPT_STOPPED : RUNSCRIPT_OK;
24137 1399085 }
24138
24139 // When j_instance is null, that means the interperter is fully in charge.
24140 // Otherwise, the JIT may still call this function for the many commands that are not compiled, or
24141 // during the period before a function is "hot" enough to have been compiled.
24142 1370766379 int32_t run_script_int(JittedScriptInstance* j_instance)
24143 {
24144 1370766379 bool is_jitted = j_instance;
24145 1370766379 ScriptType type = curScriptType;
24146 1370766379 word script = curScriptNum;
24147 1370766379 int32_t i = curScriptIndex;
24148
24149 1370766379 current_zasm_command=(ASM_DEFINE)0; // this is actually SETV, but we never will print that as a context string, so it's fine.
24150
24151 1370766379 int commands_run = 0;
24152
2/2
✓ Branch 0 taken 1370765555 times.
✓ Branch 1 taken 824 times.
1370766379 bool old_script_funcrun = script_funcrun && curscript->meta.ffscript_v < 23;
24153
2/2
✓ Branch 0 taken 1370764334 times.
✓ Branch 1 taken 2045 times.
1370766379 if(!is_jitted)
24154 {
24155
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2045 times.
2045 if(ri->waitframes)
24156 {
24157 --ri->waitframes;
24158 return RUNSCRIPT_OK;
24159 }
24160 2045 zs_vargs.clear();
24161
24162 #ifdef _FFDISSASSEMBLY
24163
24164 if(curscript->zasm[ri->pc].command != 0xFFFF)
24165 {
24166 #ifdef _FFONESCRIPTDISSASSEMBLY
24167 zc_trace_clear();
24168 #endif
24169
24170 switch(type)
24171 {
24172 case ScriptType::FFC:
24173 al_trace("\nStart of FFC script %i processing on FFC %i:\n", script, i);
24174 break;
24175
24176 case ScriptType::Item:
24177 al_trace("\nStart of item script %i processing:\n", script);
24178 break;
24179
24180 case ScriptType::Global:
24181 al_trace("\nStart of global script %I processing:\n", script);
24182 break;
24183 }
24184 }
24185
24186 #endif
24187 2045 }
24188
24189 // This is used to help debug differences w/ the JIT implementation. See scripts/jit_runtime_debug.py.
24190 1370766379 bool is_debugging = script_debug_is_runtime_debugging() == 2;
24191 1370766379 bool increment = true;
24192
5/8
✓ Branch 0 taken 237 times.
✓ Branch 1 taken 1370766142 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 237 times.
✓ Branch 4 taken 237 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 237 times.
✗ Branch 7 not taken.
1370766379 static std::vector<ffscript> empty_zasm = {{0xFFFF}};
24193
1/2
✓ Branch 0 taken 1370766379 times.
✗ Branch 1 not taken.
1370766379 const auto& zasm = curscript->valid() ? curscript->zasm_script->zasm : empty_zasm;
24194 1370766379 word scommand = zasm[ri->pc].command;
24195 1370766379 bool hit_invalid_zasm = false;
24196 1370766379 bool no_dealloc = false;
24197
2/2
✓ Branch 0 taken 1463 times.
✓ Branch 1 taken 1564712912 times.
1564714375 while(scommand != 0xFFFF)
24198 {
24199 1564712912 const auto& op = zasm[ri->pc];
24200 1564712912 scommand = op.command;
24201 1564712912 sarg1 = op.arg1;
24202 1564712912 sarg2 = op.arg2;
24203 1564712912 sarg3 = op.arg3;
24204 1564712912 sargstr = op.strptr;
24205 1564712912 sargvec = op.vecptr;
24206
24207 1564712912 current_zasm_command = (ASM_DEFINE)scommand;
24208
24209
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 1564712912 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1564712912 if (is_debugging && (!is_jitted || !j_instance->sequence_mode || commands_run > 0))
24210 {
24211 runtime_script_debug_handle->pre_command();
24212 }
24213
24214 1564712912 bool waiting = true;
24215
6/6
✓ Branch 0 taken 1530155414 times.
✓ Branch 1 taken 6653892 times.
✓ Branch 2 taken 2935192 times.
✓ Branch 3 taken 3500 times.
✓ Branch 4 taken 24957279 times.
✓ Branch 5 taken 7635 times.
1564712912 switch(scommand) //Handle waitframe-type commands first
24216 {
24217 case WAITDRAW:
24218 {
24219
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6653892 times.
6653892 if(script_funcrun)
24220 scommand = NOP;
24221
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 6653892 times.
✗ Branch 2 not taken.
6653892 else switch(type)
24222 {
24223 case ScriptType::EngineSubscreen: //ignore waitdraws
24224 Z_scripterrlog("'Waitdraw()' is invalid in subscreen scripts, will be ignored\n");
24225 scommand = NOP;
24226 break;
24227 case ScriptType::Generic:
24228 case ScriptType::GenericFrozen: //ignore waitdraws
24229 Z_scripterrlog("'Waitdraw()' is invalid in generic scripts, will be ignored\n");
24230 scommand = NOP;
24231 break;
24232 }
24233 6653892 break;
24234 }
24235 case WAITTO:
24236 {
24237
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2935192 times.
2935192 if(script_funcrun)
24238 scommand = NOP;
24239
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 2935192 times.
2935192 else switch(type)
24240 {
24241 case ScriptType::GenericFrozen:
24242 //ignore, no warn/error
24243 scommand = NOP;
24244 break;
24245 case ScriptType::Generic:
24246 {
24247 2935192 user_genscript& scr = user_genscript::get(script);
24248 2935192 int32_t target = get_register(sarg1)/10000L;
24249 2935192 bool atleast = get_register(sarg2)!=0;
24250
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2935192 times.
2935192 if(unsigned(target) > SCR_TIMING_END_FRAME)
24251 {
24252 Z_scripterrlog("Invalid value '%d' provided to 'WaitTo()'\n", target);
24253 scommand = NOP;
24254 break;
24255 }
24256
2/4
✓ Branch 0 taken 2935164 times.
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2935192 if(genscript_timing == target ||
24257
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2935164 times.
2935164 (atleast && genscript_timing < target))
24258 {
24259 //Already that time, skip the command
24260 28 scommand = NOP;
24261 28 break;
24262 }
24263 2935164 scr.waituntil = scr_timing(target);
24264 2935164 scr.wait_atleast = atleast;
24265 2935164 break;
24266 }
24267 default:
24268 Z_scripterrlog("'WaitTo()' is only valid in 'generic' scripts!\n");
24269 scommand = NOP;
24270 break;
24271 }
24272 2935192 break;
24273 }
24274 case WAITEVENT:
24275 {
24276
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3500 times.
3500 if(script_funcrun)
24277 scommand = NOP;
24278
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 3500 times.
3500 else switch(type)
24279 {
24280 case ScriptType::GenericFrozen:
24281 scommand = WAITFRAME;
24282 ri->d[0] = GENSCR_EVENT_NIL*10000; //no event
24283 break;
24284 case ScriptType::Generic:
24285 {
24286 3500 user_genscript& scr = user_genscript::get(script);
24287 3500 scr.waitevent = true;
24288 3500 break;
24289 }
24290 default:
24291 Z_scripterrlog("'WaitEvent()' is only valid in 'generic' scripts!\n");
24292 scommand = NOP;
24293 break;
24294 }
24295 3500 break;
24296 }
24297 case WAITFRAME:
24298 {
24299
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24957279 times.
24957279 if(script_funcrun)
24300 scommand = NOP;
24301
2/2
✓ Branch 0 taken 21838972 times.
✓ Branch 1 taken 3118307 times.
24957279 else switch(type)
24302 {
24303 case ScriptType::Generic:
24304 {
24305 3118307 user_genscript& scr = user_genscript::get(script);
24306 3118307 scr.waituntil = SCR_TIMING_START_FRAME;
24307 3118307 scr.wait_atleast = false;
24308 3118307 break;
24309 }
24310 }
24311 24957279 break;
24312 }
24313 case WAITFRAMESR:
24314 {
24315 7635 auto count = get_register(sarg1);
24316
3/4
✓ Branch 0 taken 7635 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 760 times.
✓ Branch 3 taken 6875 times.
7635 if(script_funcrun || count <= 0)
24317 {
24318 760 scommand = NOP;
24319 760 break;
24320 }
24321 6875 auto frames = count/10000;
24322
1/2
✓ Branch 0 taken 6875 times.
✗ Branch 1 not taken.
6875 if(count%10000) ++frames; //round up decimals
24323 6875 ri->waitframes = frames-1; //this frame doesn't count
24324
2/2
✓ Branch 0 taken 6562 times.
✓ Branch 1 taken 313 times.
6875 switch(type)
24325 {
24326 case ScriptType::Generic:
24327 {
24328 313 user_genscript& scr = user_genscript::get(script);
24329 313 scr.waituntil = SCR_TIMING_START_FRAME;
24330 313 scr.wait_atleast = false;
24331 313 break;
24332 }
24333 }
24334 6875 break;
24335 }
24336 1530155414 default: waiting = false;
24337 1530155414 }
24338
4/4
✓ Branch 0 taken 34557498 times.
✓ Branch 1 taken 1530155414 times.
✓ Branch 2 taken 788 times.
✓ Branch 3 taken 34556710 times.
1564712912 if(waiting && scommand != NOP)
24339 {
24340
2/2
✓ Branch 0 taken 1218 times.
✓ Branch 1 taken 34555492 times.
34556710 if (is_jitted)
24341 34555492 j_instance->should_wait = true;
24342 34556710 break;
24343 }
24344
24345 1530156202 numInstructions++;
24346
2/2
✓ Branch 0 taken 1528626126 times.
✓ Branch 1 taken 1530076 times.
1530156202 if(numInstructions==hangcount) // No need to check frequently
24347 {
24348 1530076 numInstructions=0;
24349 1530076 poll_keyboard();
24350 1530076 checkQuitKeys();
24351
1/2
✓ Branch 0 taken 1530076 times.
✗ Branch 1 not taken.
1530076 if(Quit)
24352 scommand=0xFFFF;
24353 1530076 }
24354
24355
243/593
✗ Branch 0 not taken.
✓ Branch 1 taken 1388786 times.
✓ Branch 2 taken 991392 times.
✓ Branch 3 taken 1392547 times.
✓ Branch 4 taken 108269 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 212470599 times.
✓ Branch 9 taken 52004397 times.
✓ Branch 10 taken 89948598 times.
✓ Branch 11 taken 2984544 times.
✓ Branch 12 taken 3274214 times.
✓ Branch 13 taken 569832 times.
✓ Branch 14 taken 3089773 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 7541432 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 5672380 times.
✓ Branch 20 taken 10394983 times.
✓ Branch 21 taken 20120034 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 201826 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 3398 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 14188632 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 13664241 times.
✓ Branch 34 taken 10105657 times.
✓ Branch 35 taken 80 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 2791389 times.
✓ Branch 38 taken 1998575 times.
✓ Branch 39 taken 70795 times.
✗ Branch 40 not taken.
✓ Branch 41 taken 23952 times.
✗ Branch 42 not taken.
✓ Branch 43 taken 9768934 times.
✗ Branch 44 not taken.
✓ Branch 45 taken 6680540 times.
✗ Branch 46 not taken.
✓ Branch 47 taken 100 times.
✓ Branch 48 taken 3916 times.
✓ Branch 49 taken 196075 times.
✓ Branch 50 taken 17252 times.
✓ Branch 51 taken 14918 times.
✓ Branch 52 taken 32282 times.
✓ Branch 53 taken 18404 times.
✗ Branch 54 not taken.
✓ Branch 55 taken 980737 times.
✓ Branch 56 taken 2544 times.
✗ Branch 57 not taken.
✓ Branch 58 taken 14127 times.
✓ Branch 59 taken 2 times.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✓ Branch 73 taken 234 times.
✗ Branch 74 not taken.
✓ Branch 75 taken 137140 times.
✗ Branch 76 not taken.
✓ Branch 77 taken 906 times.
✗ Branch 78 not taken.
✓ Branch 79 taken 115 times.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✓ Branch 86 taken 2121 times.
✓ Branch 87 taken 1377 times.
✗ Branch 88 not taken.
✓ Branch 89 taken 8306 times.
✓ Branch 90 taken 3523319 times.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✗ Branch 93 not taken.
✗ Branch 94 not taken.
✓ Branch 95 taken 15 times.
✗ Branch 96 not taken.
✗ Branch 97 not taken.
✓ Branch 98 taken 10089782 times.
✓ Branch 99 taken 6556 times.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✓ Branch 102 taken 155310 times.
✗ Branch 103 not taken.
✓ Branch 104 taken 678025 times.
✓ Branch 105 taken 249892 times.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✗ Branch 108 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
✓ Branch 111 taken 3719887 times.
✓ Branch 112 taken 80068802 times.
✓ Branch 113 taken 4965357 times.
✓ Branch 114 taken 27016621 times.
✓ Branch 115 taken 4974468 times.
✓ Branch 116 taken 352043 times.
✗ Branch 117 not taken.
✗ Branch 118 not taken.
✗ Branch 119 not taken.
✓ Branch 120 taken 4 times.
✓ Branch 121 taken 317888 times.
✗ Branch 122 not taken.
✓ Branch 123 taken 34296 times.
✗ Branch 124 not taken.
✓ Branch 125 taken 12533 times.
✗ Branch 126 not taken.
✓ Branch 127 taken 34 times.
✗ Branch 128 not taken.
✗ Branch 129 not taken.
✗ Branch 130 not taken.
✗ Branch 131 not taken.
✗ Branch 132 not taken.
✗ Branch 133 not taken.
✓ Branch 134 taken 28 times.
✓ Branch 135 taken 287 times.
✓ Branch 136 taken 33606 times.
✓ Branch 137 taken 12284 times.
✗ Branch 138 not taken.
✗ Branch 139 not taken.
✓ Branch 140 taken 3 times.
✗ Branch 141 not taken.
✓ Branch 142 taken 123 times.
✓ Branch 143 taken 127 times.
✓ Branch 144 taken 5436 times.
✗ Branch 145 not taken.
✗ Branch 146 not taken.
✗ Branch 147 not taken.
✓ Branch 148 taken 63830 times.
✓ Branch 149 taken 357 times.
✓ Branch 150 taken 236 times.
✓ Branch 151 taken 1 times.
✗ Branch 152 not taken.
✗ Branch 153 not taken.
✗ Branch 154 not taken.
✗ Branch 155 not taken.
✓ Branch 156 taken 14 times.
✗ Branch 157 not taken.
✗ Branch 158 not taken.
✓ Branch 159 taken 1351 times.
✓ Branch 160 taken 2768 times.
✓ Branch 161 taken 1860392 times.
✓ Branch 162 taken 5661515 times.
✓ Branch 163 taken 585769 times.
✗ Branch 164 not taken.
✗ Branch 165 not taken.
✗ Branch 166 not taken.
✗ Branch 167 not taken.
✓ Branch 168 taken 3585254 times.
✗ Branch 169 not taken.
✓ Branch 170 taken 182518 times.
✗ Branch 171 not taken.
✓ Branch 172 taken 10 times.
✗ Branch 173 not taken.
✓ Branch 174 taken 223 times.
✓ Branch 175 taken 11 times.
✗ Branch 176 not taken.
✗ Branch 177 not taken.
✓ Branch 178 taken 11 times.
✗ Branch 179 not taken.
✗ Branch 180 not taken.
✓ Branch 181 taken 24 times.
✓ Branch 182 taken 87 times.
✓ Branch 183 taken 92 times.
✗ Branch 184 not taken.
✗ Branch 185 not taken.
✗ Branch 186 not taken.
✓ Branch 187 taken 31 times.
✗ Branch 188 not taken.
✓ Branch 189 taken 1064 times.
✓ Branch 190 taken 130 times.
✗ Branch 191 not taken.
✗ Branch 192 not taken.
✓ Branch 193 taken 450 times.
✓ Branch 194 taken 4781 times.
✗ Branch 195 not taken.
✓ Branch 196 taken 112 times.
✓ Branch 197 taken 234 times.
✗ Branch 198 not taken.
✓ Branch 199 taken 932 times.
✓ Branch 200 taken 53 times.
✗ Branch 201 not taken.
✗ Branch 202 not taken.
✗ Branch 203 not taken.
✗ Branch 204 not taken.
✗ Branch 205 not taken.
✗ Branch 206 not taken.
✗ Branch 207 not taken.
✗ Branch 208 not taken.
✗ Branch 209 not taken.
✗ Branch 210 not taken.
✓ Branch 211 taken 14 times.
✗ Branch 212 not taken.
✓ Branch 213 taken 54 times.
✓ Branch 214 taken 18 times.
✓ Branch 215 taken 12 times.
✗ Branch 216 not taken.
✗ Branch 217 not taken.
✗ Branch 218 not taken.
✓ Branch 219 taken 303017 times.
✗ Branch 220 not taken.
✓ Branch 221 taken 22558 times.
✗ Branch 222 not taken.
✓ Branch 223 taken 3595 times.
✓ Branch 224 taken 31517 times.
✓ Branch 225 taken 117 times.
✓ Branch 226 taken 11796078 times.
✓ Branch 227 taken 1279180 times.
✓ Branch 228 taken 176099 times.
✗ Branch 229 not taken.
✗ Branch 230 not taken.
✓ Branch 231 taken 20064 times.
✗ Branch 232 not taken.
✗ Branch 233 not taken.
✗ Branch 234 not taken.
✓ Branch 235 taken 25461489 times.
✓ Branch 236 taken 257 times.
✗ Branch 237 not taken.
✓ Branch 238 taken 364942 times.
✓ Branch 239 taken 50 times.
✓ Branch 240 taken 13670631 times.
✓ Branch 241 taken 18282859 times.
✓ Branch 242 taken 3182 times.
✗ Branch 243 not taken.
✗ Branch 244 not taken.
✗ Branch 245 not taken.
✗ Branch 246 not taken.
✗ Branch 247 not taken.
✓ Branch 248 taken 10 times.
✗ Branch 249 not taken.
✗ Branch 250 not taken.
✓ Branch 251 taken 57032 times.
✗ Branch 252 not taken.
✗ Branch 253 not taken.
✗ Branch 254 not taken.
✗ Branch 255 not taken.
✗ Branch 256 not taken.
✗ Branch 257 not taken.
✗ Branch 258 not taken.
✗ Branch 259 not taken.
✗ Branch 260 not taken.
✓ Branch 261 taken 7084216 times.
✗ Branch 262 not taken.
✗ Branch 263 not taken.
✗ Branch 264 not taken.
✗ Branch 265 not taken.
✗ Branch 266 not taken.
✗ Branch 267 not taken.
✓ Branch 268 taken 3560 times.
✓ Branch 269 taken 100 times.
✗ Branch 270 not taken.
✗ Branch 271 not taken.
✗ Branch 272 not taken.
✗ Branch 273 not taken.
✗ Branch 274 not taken.
✗ Branch 275 not taken.
✗ Branch 276 not taken.
✗ Branch 277 not taken.
✗ Branch 278 not taken.
✗ Branch 279 not taken.
✗ Branch 280 not taken.
✓ Branch 281 taken 3 times.
✗ Branch 282 not taken.
✗ Branch 283 not taken.
✗ Branch 284 not taken.
✗ Branch 285 not taken.
✗ Branch 286 not taken.
✗ Branch 287 not taken.
✗ Branch 288 not taken.
✗ Branch 289 not taken.
✗ Branch 290 not taken.
✗ Branch 291 not taken.
✗ Branch 292 not taken.
✗ Branch 293 not taken.
✗ Branch 294 not taken.
✓ Branch 295 taken 73 times.
✓ Branch 296 taken 6 times.
✓ Branch 297 taken 137140 times.
✓ Branch 298 taken 10 times.
✗ Branch 299 not taken.
✗ Branch 300 not taken.
✓ Branch 301 taken 3218 times.
✓ Branch 302 taken 4 times.
✓ Branch 303 taken 26 times.
✓ Branch 304 taken 65124359 times.
✓ Branch 305 taken 53527326 times.
✗ Branch 306 not taken.
✗ Branch 307 not taken.
✓ Branch 308 taken 6689298 times.
✓ Branch 309 taken 3 times.
✓ Branch 310 taken 92290 times.
✓ Branch 311 taken 67924379 times.
✓ Branch 312 taken 2918715 times.
✗ Branch 313 not taken.
✓ Branch 314 taken 556 times.
✗ Branch 315 not taken.
✗ Branch 316 not taken.
✗ Branch 317 not taken.
✓ Branch 318 taken 6749621 times.
✓ Branch 319 taken 507719 times.
✓ Branch 320 taken 1587310 times.
✓ Branch 321 taken 1564594 times.
✗ Branch 322 not taken.
✗ Branch 323 not taken.
✗ Branch 324 not taken.
✓ Branch 325 taken 104057684 times.
✗ Branch 326 not taken.
✗ Branch 327 not taken.
✓ Branch 328 taken 812209 times.
✗ Branch 329 not taken.
✗ Branch 330 not taken.
✗ Branch 331 not taken.
✓ Branch 332 taken 20309982 times.
✓ Branch 333 taken 45955 times.
✓ Branch 334 taken 19839774 times.
✗ Branch 335 not taken.
✗ Branch 336 not taken.
✓ Branch 337 taken 3427790 times.
✗ Branch 338 not taken.
✗ Branch 339 not taken.
✓ Branch 340 taken 1621 times.
✗ Branch 341 not taken.
✓ Branch 342 taken 10 times.
✗ Branch 343 not taken.
✓ Branch 344 taken 303089179 times.
✓ Branch 345 taken 3358372 times.
✗ Branch 346 not taken.
✗ Branch 347 not taken.
✓ Branch 348 taken 6 times.
✓ Branch 349 taken 137973 times.
✓ Branch 350 taken 3598 times.
✓ Branch 351 taken 265720 times.
✗ Branch 352 not taken.
✗ Branch 353 not taken.
✗ Branch 354 not taken.
✓ Branch 355 taken 41814 times.
✗ Branch 356 not taken.
✓ Branch 357 taken 5902195 times.
✓ Branch 358 taken 250385 times.
✗ Branch 359 not taken.
✓ Branch 360 taken 16 times.
✗ Branch 361 not taken.
✗ Branch 362 not taken.
✗ Branch 363 not taken.
✓ Branch 364 taken 14 times.
✓ Branch 365 taken 4797 times.
✓ Branch 366 taken 56 times.
✓ Branch 367 taken 935 times.
✗ Branch 368 not taken.
✗ Branch 369 not taken.
✗ Branch 370 not taken.
✓ Branch 371 taken 2 times.
✗ Branch 372 not taken.
✓ Branch 373 taken 7914 times.
✓ Branch 374 taken 4623 times.
✓ Branch 375 taken 8488 times.
✗ Branch 376 not taken.
✓ Branch 377 taken 13037 times.
✓ Branch 378 taken 1570475 times.
✓ Branch 379 taken 162607 times.
✓ Branch 380 taken 602349 times.
✓ Branch 381 taken 30 times.
✓ Branch 382 taken 1820501 times.
✓ Branch 383 taken 2674 times.
✓ Branch 384 taken 2918055 times.
✗ Branch 385 not taken.
✗ Branch 386 not taken.
✗ Branch 387 not taken.
✗ Branch 388 not taken.
✗ Branch 389 not taken.
✗ Branch 390 not taken.
✓ Branch 391 taken 969 times.
✓ Branch 392 taken 648 times.
✗ Branch 393 not taken.
✓ Branch 394 taken 3867 times.
✗ Branch 395 not taken.
✓ Branch 396 taken 10744 times.
✗ Branch 397 not taken.
✗ Branch 398 not taken.
✗ Branch 399 not taken.
✗ Branch 400 not taken.
✗ Branch 401 not taken.
✓ Branch 402 taken 2 times.
✓ Branch 403 taken 3 times.
✓ Branch 404 taken 1389 times.
✓ Branch 405 taken 11645 times.
✓ Branch 406 taken 15 times.
✗ Branch 407 not taken.
✗ Branch 408 not taken.
✗ Branch 409 not taken.
✓ Branch 410 taken 5660 times.
✗ Branch 411 not taken.
✗ Branch 412 not taken.
✓ Branch 413 taken 427914 times.
✗ Branch 414 not taken.
✓ Branch 415 taken 2004 times.
✗ Branch 416 not taken.
✗ Branch 417 not taken.
✓ Branch 418 taken 140 times.
✓ Branch 419 taken 3807 times.
✗ Branch 420 not taken.
✗ Branch 421 not taken.
✗ Branch 422 not taken.
✗ Branch 423 not taken.
✗ Branch 424 not taken.
✗ Branch 425 not taken.
✗ Branch 426 not taken.
✗ Branch 427 not taken.
✗ Branch 428 not taken.
✗ Branch 429 not taken.
✓ Branch 430 taken 58103417 times.
✗ Branch 431 not taken.
✗ Branch 432 not taken.
✓ Branch 433 taken 6366 times.
✓ Branch 434 taken 6042586 times.
✗ Branch 435 not taken.
✓ Branch 436 taken 5603 times.
✗ Branch 437 not taken.
✓ Branch 438 taken 370 times.
✗ Branch 439 not taken.
✗ Branch 440 not taken.
✗ Branch 441 not taken.
✗ Branch 442 not taken.
✗ Branch 443 not taken.
✗ Branch 444 not taken.
✗ Branch 445 not taken.
✗ Branch 446 not taken.
✗ Branch 447 not taken.
✗ Branch 448 not taken.
✓ Branch 449 taken 52 times.
✗ Branch 450 not taken.
✗ Branch 451 not taken.
✗ Branch 452 not taken.
✓ Branch 453 taken 598 times.
✓ Branch 454 taken 32179030 times.
✓ Branch 455 taken 166704 times.
✗ Branch 456 not taken.
✓ Branch 457 taken 601509 times.
✓ Branch 458 taken 8420 times.
✗ Branch 459 not taken.
✗ Branch 460 not taken.
✓ Branch 461 taken 296065 times.
✗ Branch 462 not taken.
✗ Branch 463 not taken.
✗ Branch 464 not taken.
✗ Branch 465 not taken.
✓ Branch 466 taken 5 times.
✓ Branch 467 taken 364895 times.
✓ Branch 468 taken 3 times.
✓ Branch 469 taken 3 times.
✓ Branch 470 taken 382 times.
✓ Branch 471 taken 118 times.
✗ Branch 472 not taken.
✗ Branch 473 not taken.
✗ Branch 474 not taken.
✗ Branch 475 not taken.
✗ Branch 476 not taken.
✗ Branch 477 not taken.
✓ Branch 478 taken 26757 times.
✓ Branch 479 taken 3512 times.
✓ Branch 480 taken 146 times.
✗ Branch 481 not taken.
✗ Branch 482 not taken.
✗ Branch 483 not taken.
✗ Branch 484 not taken.
✗ Branch 485 not taken.
✗ Branch 486 not taken.
✗ Branch 487 not taken.
✗ Branch 488 not taken.
✓ Branch 489 taken 49289145 times.
✗ Branch 490 not taken.
✗ Branch 491 not taken.
✗ Branch 492 not taken.
✗ Branch 493 not taken.
✓ Branch 494 taken 4 times.
✓ Branch 495 taken 42 times.
✓ Branch 496 taken 9 times.
✓ Branch 497 taken 11953 times.
✓ Branch 498 taken 2 times.
✗ Branch 499 not taken.
✗ Branch 500 not taken.
✓ Branch 501 taken 30 times.
✗ Branch 502 not taken.
✗ Branch 503 not taken.
✗ Branch 504 not taken.
✗ Branch 505 not taken.
✗ Branch 506 not taken.
✗ Branch 507 not taken.
✓ Branch 508 taken 66 times.
✗ Branch 509 not taken.
✓ Branch 510 taken 14 times.
✗ Branch 511 not taken.
✗ Branch 512 not taken.
✗ Branch 513 not taken.
✗ Branch 514 not taken.
✗ Branch 515 not taken.
✗ Branch 516 not taken.
✗ Branch 517 not taken.
✓ Branch 518 taken 1798 times.
✓ Branch 519 taken 3596 times.
✗ Branch 520 not taken.
✗ Branch 521 not taken.
✓ Branch 522 taken 440764 times.
✗ Branch 523 not taken.
✗ Branch 524 not taken.
✗ Branch 525 not taken.
✗ Branch 526 not taken.
✗ Branch 527 not taken.
✗ Branch 528 not taken.
✗ Branch 529 not taken.
✗ Branch 530 not taken.
✗ Branch 531 not taken.
✗ Branch 532 not taken.
✗ Branch 533 not taken.
✗ Branch 534 not taken.
✗ Branch 535 not taken.
✗ Branch 536 not taken.
✗ Branch 537 not taken.
✓ Branch 538 taken 15 times.
✗ Branch 539 not taken.
✓ Branch 540 taken 2511 times.
✓ Branch 541 taken 1482 times.
✗ Branch 542 not taken.
✗ Branch 543 not taken.
✗ Branch 544 not taken.
✓ Branch 545 taken 5 times.
✗ Branch 546 not taken.
✗ Branch 547 not taken.
✗ Branch 548 not taken.
✗ Branch 549 not taken.
✗ Branch 550 not taken.
✗ Branch 551 not taken.
✗ Branch 552 not taken.
✗ Branch 553 not taken.
✗ Branch 554 not taken.
✗ Branch 555 not taken.
✗ Branch 556 not taken.
✗ Branch 557 not taken.
✗ Branch 558 not taken.
✓ Branch 559 taken 58074 times.
✓ Branch 560 taken 463835 times.
✗ Branch 561 not taken.
✗ Branch 562 not taken.
✗ Branch 563 not taken.
✗ Branch 564 not taken.
✓ Branch 565 taken 8 times.
✗ Branch 566 not taken.
✗ Branch 567 not taken.
✗ Branch 568 not taken.
✗ Branch 569 not taken.
✗ Branch 570 not taken.
✓ Branch 571 taken 14870 times.
✓ Branch 572 taken 17877 times.
✗ Branch 573 not taken.
✗ Branch 574 not taken.
✗ Branch 575 not taken.
✗ Branch 576 not taken.
✗ Branch 577 not taken.
✓ Branch 578 taken 828 times.
✗ Branch 579 not taken.
✗ Branch 580 not taken.
✗ Branch 581 not taken.
✗ Branch 582 not taken.
✓ Branch 583 taken 76234 times.
✗ Branch 584 not taken.
✓ Branch 585 taken 1579022 times.
✓ Branch 586 taken 796 times.
✓ Branch 587 taken 3237854 times.
✓ Branch 588 taken 1428 times.
✓ Branch 589 taken 1578226 times.
✗ Branch 590 not taken.
✓ Branch 591 taken 240 times.
✓ Branch 592 taken 2654 times.
1530156202 switch(scommand)
24356 {
24357 //always first
24358 case 0xFFFF: //invalid command
24359 {
24360 3 const char* type_str = ScriptTypeToString(type);
24361
1/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
3 switch(type)
24362 {
24363 case ScriptType::FFC:
24364 zprint("%s Script %s has exited.\n", type_str, ffcmap[i].scriptname.c_str()); break;
24365 case ScriptType::NPC:
24366 zprint("%s Script %s has exited.\n", type_str, npcmap[i].scriptname.c_str()); break;
24367 case ScriptType::Lwpn:
24368 zprint("%s Script %s has exited.\n", type_str, lwpnmap[i].scriptname.c_str()); break;
24369 case ScriptType::Ewpn:
24370 zprint("%s Script %s has exited.\n", type_str, ewpnmap[i].scriptname.c_str()); break;
24371 case ScriptType::ItemSprite:
24372 zprint("%s Script %s has exited.\n", type_str, itemspritemap[i].scriptname.c_str()); break;
24373 case ScriptType::Item:
24374 zprint("%s Script %s has exited.\n", type_str, itemmap[i].scriptname.c_str()); break;
24375 case ScriptType::Global:
24376 3 zprint("%s Script %s has exited.\n", type_str, globalmap[i].scriptname.c_str()); break;
24377 case ScriptType::Hero:
24378 zprint("%s Script %s has exited.\n", type_str, playermap[i].scriptname.c_str()); break;
24379 case ScriptType::Screen:
24380 zprint("%s Script %s has exited.\n", type_str, screenmap[i].scriptname.c_str()); break;
24381 case ScriptType::OnMap:
24382 case ScriptType::DMap:
24383 case ScriptType::ScriptedActiveSubscreen:
24384 case ScriptType::ScriptedPassiveSubscreen:
24385 zprint("%s Script %s has exited.\n", type_str, dmapmap[i].scriptname.c_str()); break;
24386 case ScriptType::Combo: zprint("%s Script %s has exited.\n", type_str, comboscriptmap[i].scriptname.c_str()); break;
24387
24388 default: break;
24389 }
24390 3 break;
24391 }
24392 case QUIT:
24393 92290 scommand = 0xFFFF;
24394 92290 break;
24395 case QUIT_NO_DEALLOC:
24396 scommand = 0xFFFF;
24397 no_dealloc = true;
24398 break;
24399
24400 case NOP: //No Operation. Do nothing. -Em
24401 {
24402 // While we are here, skip many NOPs in a row to avoid the overhead
24403 // of the interpreter loop. This is especially good for how `zasm_optimize`
24404 // works, since it replaces many commands with a sequence of NOPs.
24405 // No need to do a bounds check - the last command should always be 0xFFFF.
24406
3/4
✓ Branch 0 taken 67924379 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60019709 times.
✓ Branch 3 taken 7904670 times.
67924379 if (is_debugging || is_jitted)
24407 60019709 break;
24408
2/2
✓ Branch 0 taken 9684998 times.
✓ Branch 1 taken 7904670 times.
17589668 while (zasm[ri->pc + 1].command == NOP)
24409 9684998 ri->pc++;
24410 7904670 break;
24411 }
24412 case GOTO:
24413 {
24414
1/2
✓ Branch 0 taken 2918715 times.
✗ Branch 1 not taken.
2918715 if(sarg1 < 0 )
24415 {
24416 goto_err("GOTO");
24417 scommand = 0xFFFF;
24418 break;
24419 }
24420
24421 // When is_jitted is true, GOTO can only be processed here when j_instance->sequence_mode is false.
24422 // Track back edges (jumps to a loop head). The JIT will compiled the current
24423 // function if this is called enough.
24424
4/4
✓ Branch 0 taken 2493634 times.
✓ Branch 1 taken 425081 times.
✓ Branch 2 taken 58180 times.
✓ Branch 3 taken 2435454 times.
2918715 if (is_jitted && ri->pc > sarg1)
24425 2435454 jit_profiler_increment_function_back_edge(j_instance, sarg1);
24426
24427 2918715 ri->pc = sarg1;
24428 2918715 increment = false;
24429 2918715 break;
24430 }
24431 case GOTOR:
24432 {
24433 if(sarg1 < 0 )
24434 {
24435 goto_err("GOTOR");
24436 scommand = 0xFFFF;
24437 break;
24438 }
24439 ri->pc = (get_register(sarg1) / 10000) - 1;
24440 increment = false;
24441 }
24442 break;
24443
24444 case GOTOTRUE:
24445
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 519 times.
556 if(check_cmp(CMP_EQ))
24446 {
24447
1/2
✓ Branch 0 taken 519 times.
✗ Branch 1 not taken.
519 if(sarg1 < 0 )
24448 {
24449 goto_err("GOTOTRUE");
24450 scommand = 0xFFFF;
24451 break;
24452 }
24453 519 ri->pc = sarg1;
24454 519 increment = false;
24455 519 }
24456 556 break;
24457
24458 case GOTOFALSE:
24459 if(check_cmp(CMP_NE))
24460 {
24461 if(sarg1 < 0 )
24462 {
24463 goto_err("GOTOFALSE");
24464 scommand = 0xFFFF;
24465 break;
24466 }
24467 ri->pc = sarg1;
24468 increment = false;
24469 }
24470 break;
24471
24472 case GOTOMORE:
24473 if(check_cmp(CMP_GE))
24474 {
24475 if(sarg1 < 0 )
24476 {
24477 goto_err("GOTOMORE");
24478 scommand = 0xFFFF;
24479 break;
24480 }
24481 ri->pc = sarg1;
24482 increment = false;
24483 }
24484 break;
24485
24486 case GOTOLESS:
24487 if(check_cmp(get_qr(qr_GOTOLESSNOTEQUAL) ? CMP_LT : CMP_LE))
24488 {
24489 if(sarg1 < 0 )
24490 {
24491 goto_err("GOTOLESS");
24492 scommand = 0xFFFF;
24493 break;
24494 }
24495 ri->pc = sarg1;
24496 increment = false;
24497 }
24498 break;
24499
24500 case GOTOCMP:
24501 {
24502 6749621 bool run = check_cmp(sarg2);
24503
2/2
✓ Branch 0 taken 3048421 times.
✓ Branch 1 taken 3701200 times.
6749621 if(run)
24504 {
24505
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3701200 times.
3701200 if(sarg1 < 0 )
24506 {
24507 goto_err("GOTOCMP");
24508 scommand = 0xFFFF;
24509 break;
24510 }
24511 3701200 ri->pc = sarg1;
24512 3701200 increment = false;
24513 3701200 }
24514 6749621 break;
24515 }
24516
24517 case SETCMP:
24518 {
24519 507719 bool run = check_cmp(sarg2);
24520
2/2
✓ Branch 0 taken 500575 times.
✓ Branch 1 taken 7144 times.
507719 set_register(sarg1, run ? ((sarg2 & CMP_SETI) ? 10000 : 1) : 0);
24521 507719 break;
24522 }
24523
24524 case CALLFUNC:
24525 {
24526 1587310 retstack_push(ri->pc+1);
24527
1/2
✓ Branch 0 taken 1587310 times.
✗ Branch 1 not taken.
1587310 if(sarg1 < 0 )
24528 {
24529 goto_err("CALLFUNC");
24530 scommand = 0xFFFF;
24531 break;
24532 }
24533 1587310 ri->pc = sarg1;
24534 1587310 increment = false;
24535
24536 // When is_jitted is true, CALLFUNC can only be processed here when j_instance->sequence_mode is false.
24537 // And when it is called, it marks the end of run_script_int.
24538
2/2
✓ Branch 0 taken 877633 times.
✓ Branch 1 taken 709677 times.
1587310 if (is_jitted)
24539 709677 j_instance->uncompiled_command_count = commands_run + 1;
24540 1587310 break;
24541 }
24542 case RETURNFUNC:
24543 {
24544
2/2
✓ Branch 0 taken 1563770 times.
✓ Branch 1 taken 824 times.
1564594 if(auto retpc = retstack_pop())
24545 {
24546
1/2
✓ Branch 0 taken 1563770 times.
✗ Branch 1 not taken.
1563770 if(*retpc < 0)
24547 {
24548 goto_err("RETURNFUNC");
24549 scommand = 0xFFFF;
24550 break;
24551 }
24552 1563770 ri->pc = *retpc;
24553 1563770 increment = false;
24554 1563770 }
24555 else //Returned from 'void run()', QUIT
24556 {
24557 824 scommand = 0xFFFF;
24558 }
24559
24560 // When is_jitted is true, RETURNFUNC can only be processed here when j_instance->sequence_mode is false.
24561 // And when it is called, it marks the end of run_script_int.
24562
2/2
✓ Branch 0 taken 878440 times.
✓ Branch 1 taken 686154 times.
1564594 if (is_jitted)
24563 686154 j_instance->uncompiled_command_count = commands_run + 1;
24564 1564594 break;
24565 }
24566
24567 case LOOP:
24568 {
24569 if(get_register(sarg2) > 0)
24570 {
24571 ri->pc = sarg1;
24572 increment = false;
24573 }
24574 else
24575 {
24576 set_register(sarg1, sarg1 - 1);
24577 }
24578 }
24579 break;
24580
24581 case RETURN:
24582 {
24583 if (script_funcrun)
24584 break; //handled below, poorly. 'RETURNFUNC' does this better now.
24585 ri->pc = SH::read_stack(ri->sp) - 1;
24586 ++ri->sp;
24587 increment = false;
24588 break;
24589 }
24590
24591 case SETTRUE:
24592 1388786 set_register(sarg1, check_cmp(CMP_EQ) ? 1 : 0);
24593 1388786 break;
24594
24595 case SETFALSE:
24596 991392 set_register(sarg1, check_cmp(CMP_NE) ? 1 : 0);
24597 991392 break;
24598
24599 case SETMORE:
24600 1392547 set_register(sarg1, check_cmp(CMP_GE) ? 1 : 0);
24601 1392547 break;
24602
24603 case SETLESS:
24604 108269 set_register(sarg1, check_cmp(CMP_LE) ? 1 : 0);
24605 108269 break;
24606
24607 case SETTRUEI:
24608 set_register(sarg1, check_cmp(CMP_EQ) ? 10000 : 0);
24609 break;
24610
24611 case SETFALSEI:
24612 set_register(sarg1, check_cmp(CMP_NE) ? 10000 : 0);
24613 break;
24614
24615 case SETMOREI:
24616 set_register(sarg1, check_cmp(CMP_GE) ? 10000 : 0);
24617 break;
24618
24619 case SETLESSI:
24620 set_register(sarg1, check_cmp(CMP_LE) ? 10000 : 0);
24621 break;
24622
24623 case READPODARRAYR:
24624 {
24625 212470599 do_readpod(false);
24626 212470599 break;
24627 }
24628 case READPODARRAYV:
24629 {
24630 104057684 do_readpod(true);
24631 104057684 break;
24632 }
24633 case WRITEPODARRAYRR:
24634 {
24635 52004397 do_writepod(false,false);
24636 52004397 break;
24637 }
24638 case WRITEPODARRAYRV:
24639 {
24640 do_writepod(false,true);
24641 break;
24642 }
24643 case WRITEPODARRAYVR:
24644 {
24645 89948598 do_writepod(true,false);
24646 89948598 break;
24647 }
24648 case WRITEPODARRAYVV:
24649 {
24650 2984544 do_writepod(true,true);
24651 2984544 break;
24652 }
24653 case WRITEPODSTRING:
24654 {
24655 3274214 do_writepodstr();
24656 3274214 break;
24657 }
24658 case WRITEPODARRAY:
24659 {
24660 569832 do_writepodarr();
24661 569832 break;
24662 }
24663
24664 case NOT:
24665 do_not(false);
24666 break;
24667
24668 case COMPAREV:
24669 3089773 do_comp(true);
24670 3089773 break;
24671 case COMPAREV2:
24672 do_comp(true,true);
24673 break;
24674
24675 case COMPARER:
24676 7541432 do_comp(false);
24677 7541432 break;
24678
24679 case STRCMPR:
24680 do_internal_strcmp();
24681 break;
24682
24683 case STRICMPR:
24684 do_internal_stricmp();
24685 break;
24686
24687 case SETV:
24688 5672380 do_set_command(true);
24689 5672380 break;
24690
24691 case SETR:
24692 10394983 do_set_command(false);
24693 10394983 break;
24694
24695 case PUSHR:
24696 20120034 do_push(false);
24697 20120034 break;
24698
24699 case PUSHV:
24700 812209 do_push(true);
24701 812209 break;
24702
24703 case PEEK:
24704 do_peek();
24705 break;
24706 case PEEKATV:
24707 do_peekat(true);
24708 break;
24709 case STACKWRITEATRV:
24710 do_writeat(false, true);
24711 break;
24712 case STACKWRITEATVV_IF:
24713 if(!check_cmp(sarg3))
24714 break;
24715 [[fallthrough]];
24716 case STACKWRITEATVV:
24717 do_writeat(true, true);
24718 break;
24719 case POP:
24720 20309982 do_pop();
24721 20309982 break;
24722
24723 case POPARGS:
24724 201826 do_pops();
24725 201826 break;
24726
24727 case PUSHARGSR:
24728 45955 do_pushs(false);
24729 45955 break;
24730
24731 case PUSHARGSV:
24732 do_pushs(true);
24733 break;
24734
24735 case LOADI:
24736 do_loadi();
24737 break;
24738
24739 case STOREI:
24740 do_storei();
24741 break;
24742
24743 case LOADD:
24744 do_loadd();
24745 break;
24746
24747 case LOAD:
24748 19839774 do_load();
24749 19839774 break;
24750
24751 case STORED:
24752 do_stored(false);
24753 break;
24754 case STOREDV:
24755 do_stored(true);
24756 break;
24757 case STORE:
24758 3427790 do_store(false);
24759 3427790 break;
24760 case STOREV:
24761 do_store(true);
24762 break;
24763 case STORE_OBJECT:
24764 do_store_object(false);
24765 break;
24766
24767 // Note: this was never used.
24768 case ALLOCATEGMEMR:
24769 if(type == ScriptType::Global) do_allocatemem(false, false, type, i);
24770
24771 break;
24772
24773 case ALLOCATEGMEMV:
24774
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3398 times.
3398 if(type == ScriptType::Global) do_allocatemem(true, false, type, i);
24775
24776 3398 break;
24777
24778 case ALLOCATEMEMR:
24779 do_allocatemem(false, true, type, i);
24780 break;
24781
24782 case ALLOCATEMEMV:
24783 14188632 do_allocatemem(true, true, type, i);
24784 14188632 break;
24785
24786 case RESIZEARRAYR:
24787 1621 do_resize_array();
24788 1621 break;
24789 case OWNARRAYR:
24790 do_own_array(get_register(sarg1), type, i);
24791 break;
24792 case DESTROYARRAYR:
24793 do_destroy_array();
24794 break;
24795
24796 // Pre-3.0, the compiler inserted this command for every local array at the end of it scope.
24797 case DEALLOCATEMEMR:
24798 13664241 do_deallocatemem();
24799 13664241 break;
24800
24801 case SAVEGAMESTRUCTS:
24802 10 using_SRAM = 1;
24803 10 do_savegamestructs(false,false);
24804 10 using_SRAM = 0;
24805 10 break;
24806 case READGAMESTRUCTS:
24807 using_SRAM = 1;
24808 do_loadgamestructs(false,false);
24809 using_SRAM = 0;
24810 break;
24811 case ARRAYSIZE:
24812 303089179 do_arraysize();
24813 303089179 break;
24814
24815 case GETFFCSCRIPT:
24816 10105657 do_getffcscript();
24817 10105657 break;
24818 case GETITEMSCRIPT:
24819 80 do_getitemscript();
24820 80 break;
24821
24822 case LOAD_FFC:
24823 {
24824
1/2
✓ Branch 0 taken 3358372 times.
✗ Branch 1 not taken.
3358372 if (!ZScriptVersion::ffcRefIsSpriteId())
24825 {
24826 set_register(sarg1, get_register(sarg1) - 10000);
24827 break;
24828 }
24829
24830 3358372 int ffc_id = get_register(sarg1) / 10000 - 1;
24831
1/2
✓ Branch 0 taken 3358372 times.
✗ Branch 1 not taken.
3358372 if (auto ffc = ResolveFFCWithID(ffc_id))
24832 3358372 set_register(sarg1, ffc->getUID());
24833 else
24834 set_register(sarg1, 0);
24835 3358372 break;
24836 }
24837
24838 case LOAD_FFC_2:
24839 {
24840 if (!ZScriptVersion::ffcRefIsSpriteId())
24841 {
24842 set_register(sarg1, get_register(sarg2) - 10000);
24843 break;
24844 }
24845
24846 int screen = get_register(sarg1) / 10000;
24847 int index = get_register(sarg2) / 10000;
24848
24849 if (!is_in_current_region(screen))
24850 {
24851 scripting_log_error_with_context("Must use a screen in the current region. got: {}", screen);
24852 break;
24853 }
24854 if (BC::checkMapdataFFC(index) != SH::_NoError)
24855 break;
24856
24857 ffc_id_t ffc_id = get_region_screen_offset(screen)*MAXFFCS + index;
24858 if (auto ffc = ResolveFFCWithID(ffc_id))
24859 set_register(sarg1, ffc->getUID());
24860 else
24861 set_register(sarg1, 0);
24862
24863 break;
24864 }
24865
24866 case CASTBOOLI:
24867 do_boolcast(false);
24868 break;
24869
24870 case CASTBOOLF:
24871 do_boolcast(true);
24872 break;
24873
24874 case ADDV:
24875 2791389 do_add(true);
24876 2791389 break;
24877
24878 case ADDR:
24879 1998575 do_add(false);
24880 1998575 break;
24881
24882 case SUBV:
24883 70795 do_sub(true);
24884 70795 break;
24885 case SUBV2:
24886 6 do_sub(true,true);
24887 6 break;
24888
24889 case SUBR:
24890 137973 do_sub(false);
24891 137973 break;
24892
24893 case MULTV:
24894 3598 do_mult(true);
24895 3598 break;
24896
24897 case MULTR:
24898 265720 do_mult(false);
24899 265720 break;
24900
24901 case DIVV:
24902 do_div(true);
24903 break;
24904 case DIVV2:
24905 do_div(true,true);
24906 break;
24907
24908 case DIVR:
24909 23952 do_div(false);
24910 23952 break;
24911
24912 case MODV:
24913 do_mod(true);
24914 break;
24915 case MODV2:
24916 do_mod(true,true);
24917 break;
24918
24919 case MODR:
24920 41814 do_mod(false);
24921 41814 break;
24922
24923 case SINV:
24924 do_trig(true, 0);
24925 break;
24926
24927 case SINR:
24928 9768934 do_trig(false, 0);
24929 9768934 break;
24930
24931 case COSV:
24932 do_trig(true, 1);
24933 break;
24934
24935 case COSR:
24936 6680540 do_trig(false, 1);
24937 6680540 break;
24938
24939 case TANV:
24940 do_trig(true, 2);
24941 break;
24942
24943 case TANR:
24944 100 do_trig(false, 2);
24945 100 break;
24946
24947 case DEGTORAD:
24948 3916 do_degtorad();
24949 3916 break;
24950
24951 case RADTODEG:
24952 196075 do_radtodeg();
24953 196075 break;
24954
24955 case STRINGLENGTH:
24956 17252 FFCore.do_strlen(false);
24957 17252 break;
24958
24959 case ARCSINR:
24960 14918 do_asin(false);
24961 14918 break;
24962
24963 case ARCCOSR:
24964 do_acos(false);
24965 break;
24966
24967 case ARCTANR:
24968 5902195 do_arctan();
24969 5902195 break;
24970
24971 //Text ptr functions
24972 case FONTHEIGHTR:
24973 32282 do_fontheight();
24974 32282 break;
24975 case STRINGWIDTHR:
24976 18404 do_strwidth();
24977 18404 break;
24978 case CHARWIDTHR:
24979 250385 do_charwidth();
24980 250385 break;
24981 case MESSAGEWIDTHR:
24982 SET_D(rEXP1, 10000* do_msgwidth(get_register(sarg1)/10000));
24983 break;
24984 case MESSAGEHEIGHTR:
24985 SET_D(rEXP1, 10000* do_msgheight(get_register(sarg1)/10000));
24986 break;
24987 //
24988
24989 case COMBO_AT:
24990 {
24991 980737 int32_t x = get_register(sarg1) / 10000;
24992 980737 int32_t y = get_register(sarg2) / 10000;
24993 980737 x = std::clamp(x, 0, world_w - 1);
24994 980737 y = std::clamp(y, 0, world_h - 1);
24995 980737 set_register(sarg1, (int)COMBOPOS_REGION(x, y) * 10000);
24996 980737 break;
24997 }
24998
24999 case COMBO_ADJUST:
25000 {
25001 16 rpos_t rpos = (rpos_t)(get_register(sarg1) / 10000);
25002
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if (!is_valid_rpos(rpos))
25003 {
25004 set_register(sarg1, -1);
25005 break;
25006 }
25007
25008 144 auto [x, y] = COMBOXY_REGION(rpos);
25009 32 x += get_register(sarg2) / 10000;
25010 32 y += get_register(sarg3) / 10000;
25011 32 x = std::clamp(x, 0, world_w - 1);
25012 32 y = std::clamp(y, 0, world_h - 1);
25013 48 set_register(sarg1, (int)COMBOPOS_REGION(x, y) * 10000);
25014 16 break;
25015 }
25016
25017 //String.h functions 2.55 Alpha 23
25018 2544 case STRINGCOMPARE: FFCore.do_strcmp(); break;
25019 case STRINGICOMPARE: FFCore.do_stricmp(); break;
25020 14127 case STRINGCOPY: FFCore.do_strcpy(false,false); break;
25021 2 case ARRAYCOPY: FFCore.do_arraycpy(false,false); break;
25022 case STRINGNCOMPARE: FFCore.do_strncmp(); break;
25023 case STRINGNICOMPARE: FFCore.do_strnicmp(); break;
25024
25025 //More string.h functions, 19th May, 2019
25026 case XLEN: FFCore.do_xlen(false); break;
25027 case XTOI: FFCore.do_xtoi(false); break;
25028 case ILEN: FFCore.do_ilen(false); break;
25029 case ATOI: FFCore.do_atoi(false); break;
25030 case ATOL: FFCore.do_atol(false); break;
25031 case STRCSPN: FFCore.do_strcspn(); break;
25032 case STRSTR: FFCore.do_strstr(); break;
25033 14 case XTOA: FFCore.do_xtoa(); break;
25034 4797 case ITOA: FFCore.do_itoa(); break;
25035 56 case ITOACAT: FFCore.do_itoacat(); break;
25036 935 case STRCAT: FFCore.do_strcat(); break;
25037 case STRSPN: FFCore.do_strspn(); break;
25038 case STRCHR: FFCore.do_strchr(); break;
25039 case STRRCHR: FFCore.do_strrchr(); break;
25040 case XLEN2: FFCore.do_xlen2(); break;
25041 case XTOI2: FFCore.do_xtoi2(); break;
25042 case ILEN2: FFCore.do_ilen2(); break;
25043 case ATOI2: FFCore.do_atoi2(); break;
25044 case REMCHR2: FFCore.do_remchr2(); break;
25045 case UPPERTOLOWER: FFCore.do_UpperToLower(false); break;
25046 2 case LOWERTOUPPER: FFCore.do_LowerToUpper(false); break;
25047 case CONVERTCASE: FFCore.do_ConvertCase(false); break;
25048
25049 case GETNPCSCRIPT: FFCore.do_getnpcscript(); break;
25050 234 case GETCOMBOSCRIPT: FFCore.do_getcomboscript(); break;
25051 7914 case GETLWEAPONSCRIPT: FFCore.do_getlweaponscript(); break;
25052 4623 case GETEWEAPONSCRIPT: FFCore.do_geteweaponscript(); break;
25053 case GETHEROSCRIPT: FFCore.do_getheroscript(); break;
25054 137140 case GETGENERICSCRIPT: FFCore.do_getgenericscript(); break;
25055 case GETGLOBALSCRIPT: FFCore.do_getglobalscript(); break;
25056 906 case GETDMAPSCRIPT: FFCore.do_getdmapscript(); break;
25057 case GETSCREENSCRIPT: FFCore.do_getscreenscript(); break;
25058 115 case GETSPRITESCRIPT: FFCore.do_getitemspritescript(); break;
25059 case GETUNTYPEDSCRIPT: FFCore.do_getuntypedscript(); break;
25060 case GETSUBSCREENSCRIPT:FFCore.do_getsubscreenscript(); break;
25061 case GETNPCBYNAME: FFCore.do_getnpcbyname(); break;
25062 case GETITEMBYNAME: FFCore.do_getitembyname(); break;
25063 case GETCOMBOBYNAME: FFCore.do_getcombobyname(); break;
25064 case GETDMAPBYNAME: FFCore.do_getdmapbyname(); break;
25065
25066 case ABS:
25067 8488 do_abs(false);
25068 8488 break;
25069
25070 case MINR:
25071 2121 do_min(false);
25072 2121 break;
25073
25074 case MINV:
25075 do_min(true);
25076 break;
25077
25078 case MAXR:
25079 1377 do_max(false);
25080 1377 break;
25081 case MAXV:
25082 do_max(true);
25083 break;
25084 case WRAPRADIANS:
25085 8306 do_wrap_rad(false);
25086 8306 break;
25087 case WRAPDEGREES:
25088 13037 do_wrap_deg(false);
25089 13037 break;
25090
25091 case MAXVARG:
25092 1570475 FFCore.do_varg_max();
25093 1570475 break;
25094 case MINVARG:
25095 162607 FFCore.do_varg_min();
25096 162607 break;
25097 case CHOOSEVARG:
25098 602349 FFCore.do_varg_choose();
25099 602349 break;
25100 case MAKEVARGARRAY:
25101
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
30 assert(sarg1 >= 0 && sarg1 <= (int)script_object_type::last);
25102 30 FFCore.do_varg_makearray(type, i, (script_object_type)sarg1);
25103 30 break;
25104
25105 case PUSHVARGV:
25106 3523319 do_push_varg(true);
25107 3523319 break;
25108 case PUSHVARGR:
25109 1820501 do_push_varg(false);
25110 1820501 break;
25111 case PUSHVARGSV:
25112 2674 do_push_vargs(true);
25113 2674 break;
25114 case PUSHVARGSR:
25115 do_push_vargs(false);
25116 break;
25117
25118 case RNDR:
25119 2918055 do_rnd(false);
25120 2918055 break;
25121
25122 case RNDV:
25123 do_rnd(true);
25124 break;
25125
25126 case SRNDR:
25127 do_srnd(false);
25128 break;
25129
25130 case SRNDV:
25131 do_srnd(true);
25132 break;
25133
25134 case SRNDRND:
25135 do_srndrnd();
25136 break;
25137
25138 case GETRTCTIMER:
25139 15 FFCore.getRTC();
25140 15 break;
25141
25142 case FACTORIAL:
25143 do_factorial(false);
25144 break;
25145
25146 case SQROOTV:
25147 do_sqroot(true);
25148 break;
25149
25150 case SQROOTR:
25151 10089782 do_sqroot(false);
25152 10089782 break;
25153
25154 case POWERR:
25155 6556 do_power(false);
25156 6556 break;
25157 case POWERV:
25158 do_power(true);
25159 break;
25160 case POWERV2:
25161 do_power(true,true);
25162 break;
25163
25164 case LPOWERR:
25165 do_lpower(false);
25166 break;
25167 case LPOWERV:
25168 do_lpower(true);
25169 break;
25170 case LPOWERV2:
25171 do_lpower(true,true);
25172 break;
25173
25174 case IPOWERR:
25175 do_ipower(false);
25176 break;
25177
25178 case IPOWERV:
25179 do_ipower(true);
25180 break;
25181
25182 case LOG10:
25183 969 do_log10(false);
25184 969 break;
25185
25186 case LOGE:
25187 648 do_naturallog(false);
25188 648 break;
25189
25190 case ANDR:
25191 155310 do_and(false);
25192 155310 break;
25193
25194 case ANDV:
25195 do_and(true);
25196 break;
25197
25198 case ORR:
25199 3867 do_or(false);
25200 3867 break;
25201
25202 case ORV:
25203 do_or(true);
25204 break;
25205
25206 case XORR:
25207 678025 do_xor(false);
25208 678025 break;
25209
25210 case XORV:
25211 249892 do_xor(true);
25212 249892 break;
25213
25214 case NANDR:
25215 do_nand(false);
25216 break;
25217
25218 case NANDV:
25219 do_nand(true);
25220 break;
25221
25222 case NORR:
25223 do_nor(false);
25224 break;
25225
25226 case NORV:
25227 do_nor(true);
25228 break;
25229
25230 case XNORR:
25231 do_xnor(false);
25232 break;
25233
25234 case XNORV:
25235 do_xnor(true);
25236 break;
25237
25238 case BITNOT:
25239 3719887 do_bitwisenot(false);
25240 3719887 break;
25241
25242 case LSHIFTR:
25243 80068802 do_lshift(false);
25244 80068802 break;
25245
25246 case LSHIFTV:
25247 4965357 do_lshift(true);
25248 4965357 break;
25249
25250 case RSHIFTR:
25251 27016621 do_rshift(false);
25252 27016621 break;
25253
25254 case RSHIFTV:
25255 4974468 do_rshift(true);
25256 4974468 break;
25257
25258 case ANDR32:
25259 352043 do_and32(false);
25260 352043 break;
25261
25262 case ANDV32:
25263 10744 do_and32(true);
25264 10744 break;
25265
25266 case ORR32:
25267 do_or32(false);
25268 break;
25269
25270 case ORV32:
25271 do_or32(true);
25272 break;
25273
25274 case XORR32:
25275 do_xor32(false);
25276 break;
25277
25278 case XORV32:
25279 do_xor32(true);
25280 break;
25281
25282 case BITNOT32:
25283 4 do_bitwisenot32(false);
25284 4 break;
25285
25286 case LSHIFTR32:
25287 317888 do_lshift32(false);
25288 317888 break;
25289
25290 case LSHIFTV32:
25291 do_lshift32(true);
25292 break;
25293
25294 case RSHIFTR32:
25295 34296 do_rshift32(false);
25296 34296 break;
25297
25298 case RSHIFTV32:
25299 do_rshift32(true);
25300 break;
25301
25302 case TRACER:
25303 12533 FFCore.do_trace(false);
25304 12533 break;
25305
25306 case TRACELR:
25307 FFCore.do_tracel(false);
25308 break;
25309
25310 case TRACEV:
25311 34 FFCore.do_trace(true);
25312 34 break;
25313
25314 case TRACE2R:
25315 FFCore.do_tracebool(false);
25316 break;
25317
25318 //Zap and Wavy Effects
25319 case FXWAVYR:
25320 FFCore.do_fx_wavy(false);
25321 break;
25322 case FXZAPR:
25323 FFCore.do_fx_zap(false);
25324 break;
25325 //Zap and Wavy Effects
25326 case FXWAVYV:
25327 FFCore.do_fx_wavy(true);
25328 break;
25329 case FXZAPV:
25330 FFCore.do_fx_zap(true);
25331 break;
25332 case GREYSCALER:
25333 FFCore.do_greyscale(false);
25334 break;
25335 case GREYSCALEV:
25336 FFCore.do_greyscale(true);
25337 break;
25338 case MONOCHROMER:
25339 FFCore.do_monochromatic(false);
25340 break;
25341 case MONOCHROMEV:
25342 FFCore.do_monochromatic(true);
25343 break;
25344
25345 case TRACE2V:
25346 FFCore.do_tracebool(true);
25347 break;
25348
25349 case TRACE3:
25350 28 FFCore.do_tracenl();
25351 28 break;
25352
25353 case TRACE4:
25354 2 FFCore.do_cleartrace();
25355 2 break;
25356
25357 case TRACE5:
25358 3 FFCore.do_tracetobase();
25359 3 break;
25360
25361 case TRACE6:
25362 1389 FFCore.do_tracestring();
25363 1389 break;
25364
25365 case PRINTFV:
25366 287 FFCore.do_printf(true, false);
25367 287 break;
25368 case SPRINTFV:
25369 11645 do_sprintf(true, false);
25370 11645 break;
25371
25372 case PRINTFVARG:
25373 33606 FFCore.do_printf(true, true);
25374 33606 break;
25375 case SPRINTFVARG:
25376 12284 do_sprintf(true, true);
25377 12284 break;
25378 case PRINTFA:
25379 FFCore.do_printfarr();
25380 break;
25381 case SPRINTFA:
25382 do_sprintfarr();
25383 break;
25384 case ARRAYPUSH:
25385 {
25386 15 auto ptr = SH::read_stack(ri->sp + 2);
25387 15 auto val = SH::read_stack(ri->sp + 1);
25388 15 auto indx = SH::read_stack(ri->sp + 0) / 10000;
25389 15 ArrayManager am(ptr);
25390 15 SET_D(rEXP1, am.push(val,indx) ? 10000 : 0);
25391 15 break;
25392 }
25393 case ARRAYPOP:
25394 {
25395 3 auto ptr = SH::read_stack(ri->sp + 1);
25396 3 auto indx = SH::read_stack(ri->sp + 0) / 10000;
25397 3 ArrayManager am(ptr);
25398 3 SET_D(rEXP1, am.pop(indx));
25399 3 break;
25400 }
25401
25402 case BREAKPOINT:
25403 FFCore.do_breakpoint();
25404 break;
25405
25406 case WARP:
25407 do_warp(true);
25408 break;
25409
25410 case WARPR:
25411 123 do_warp(false);
25412 123 break;
25413
25414 case PITWARP:
25415 do_pitwarp(true);
25416 break;
25417
25418 case PITWARPR:
25419 127 do_pitwarp(false);
25420 127 break;
25421
25422 case SELECTAWPNV:
25423 do_selectweapon(true, 1);
25424 break;
25425
25426 case SELECTAWPNR:
25427 5660 do_selectweapon(false, 1);
25428 5660 break;
25429
25430 case SELECTBWPNV:
25431 do_selectweapon(true, 0);
25432 break;
25433
25434 case SELECTBWPNR:
25435 5436 do_selectweapon(false, 0);
25436 5436 break;
25437
25438 case SELECTXWPNR:
25439 do_selectweapon(false, 2);
25440 break;
25441
25442 case SELECTYWPNR:
25443 do_selectweapon(false, 3);
25444 break;
25445
25446 case PLAYSOUNDR:
25447 427914 do_sfx(false);
25448 427914 break;
25449
25450 case PLAYSOUNDV:
25451 do_sfx(true);
25452 break;
25453
25454 case ADJUSTSFXVOLUMER: FFCore.do_adjustsfxvolume(false); break;
25455 case ADJUSTSFXVOLUMEV: FFCore.do_adjustsfxvolume(true); break;
25456 2004 case ADJUSTVOLUMER: FFCore.do_adjustvolume(false); break;
25457 case ADJUSTVOLUMEV: FFCore.do_adjustvolume(true); break;
25458
25459 case PLAYMIDIR:
25460 63830 do_midi(false);
25461 63830 break;
25462
25463 case PLAYMIDIV:
25464 do_midi(true);
25465 break;
25466
25467 case PLAYENHMUSIC:
25468 357 do_enh_music(false);
25469 357 break;
25470
25471 case GETMUSICFILE:
25472 236 do_get_enh_music_filename(false);
25473 236 break;
25474
25475 case GETMUSICTRACK:
25476 140 do_get_enh_music_track(false);
25477 140 break;
25478
25479 case SETDMAPENHMUSIC:
25480 3807 do_set_dmap_enh_music(false);
25481 3807 break;
25482
25483 // Audio->
25484
25485 case ENDSOUNDR:
25486 1 stop_sfx(false);
25487 1 break;
25488
25489 case ENDSOUNDV:
25490 stop_sfx(true);
25491 break;
25492
25493 case PAUSESOUNDR:
25494 pause_sfx(false);
25495 break;
25496
25497 case PAUSESOUNDV:
25498 pause_sfx(true);
25499 break;
25500
25501 case RESUMESOUNDR:
25502 resume_sfx(false);
25503 break;
25504
25505 case RESUMESOUNDV:
25506 resume_sfx(true);
25507 break;
25508
25509
25510
25511 case PAUSESFX:
25512 {
25513 int32_t sound = GET_D(rINDEX)/10000;
25514 pause_sfx(sound);
25515
25516 }
25517 break;
25518
25519 case RESUMESFX:
25520 {
25521 int32_t sound = GET_D(rINDEX)/10000;
25522 resume_sfx(sound);
25523 }
25524 break;
25525
25526 case ADJUSTSFX:
25527 {
25528 do_sfx_ex(false);
25529 }
25530 break;
25531
25532 case PLAYSOUNDEX:
25533 {
25534 14 do_sfx_ex(true);
25535 }
25536 14 break;
25537
25538 case GETSFXCOMPLETION:
25539 {
25540 do_get_sfx_completion();
25541 }
25542 break;
25543
25544 case CONTINUESFX:
25545 {
25546 int32_t sound = GET_D(rINDEX)/10000;
25547 //Backend::sfx->cont_sfx(sound);
25548
25549 //! cont_sfx was not ported to the new back end!!!
25550 // I believe this restarted the loop.
25551 resume_sfx(sound);
25552 //What was the old instruction, again? Did it exist? -Z
25553 //continue_sfx(sound);
25554 }
25555 break;
25556
25557
25558 /*
25559 case STOPITEMSOUND:
25560 void stop_item_sfx(int32_t family)
25561 */
25562
25563 // Note: these have never worked.
25564 case PAUSEMUSIC:
25565 //What was the instruction prior to adding backends?
25566 //! The pauseAll() function pauses sfx, not music, so this instruction is not doing what I intended. -Z
25567 //Check AllOff() -Z
25568 //zcmusic_pause(ZCMUSIC* zcm, int32_t pause); is in zcmusic.h
25569 // midi_paused = true;
25570 //pause_all_sfx();
25571
25572 //Backend::sfx->pauseAll();
25573 break;
25574 case RESUMEMUSIC:
25575 //What was the instruction prior to adding backends?
25576 //Check AllOff() -Z
25577 //resume_all_sfx();
25578 // midi_paused = false;
25579 //Backend::sfx->resumeAll();
25580 break;
25581
25582 case MSGSTRR:
25583 1351 do_message(false);
25584 1351 break;
25585
25586 case MSGSTRV:
25587 do_message(true);
25588 break;
25589
25590 case ITEMNAME:
25591 2768 do_getitemname();
25592 2768 break;
25593
25594 case LOADLWEAPONR:
25595 1860392 do_loadlweapon(false);
25596 1860392 break;
25597
25598 case LOADLWEAPONV:
25599 do_loadlweapon(true);
25600 break;
25601
25602 case LOADEWEAPONR:
25603 5661515 do_loadeweapon(false);
25604 5661515 break;
25605
25606 case LOADEWEAPONV:
25607 do_loadeweapon(true);
25608 break;
25609
25610 case LOADITEMR:
25611 585769 do_loaditem(false);
25612 585769 break;
25613
25614 case LOADITEMV:
25615 do_loaditem(true);
25616 break;
25617
25618 case LOADITEMDATAR:
25619 58103417 do_loaditemdata(false);
25620 58103417 break;
25621
25622 //New Datatypes
25623 case LOADSHOPR:
25624 FFScript::do_loadshopdata(false);
25625 break;
25626 case LOADSHOPV:
25627 FFScript::do_loadshopdata(true);
25628 break;
25629
25630 case LOADINFOSHOPR:
25631 FFScript::do_loadinfoshopdata(false);
25632 break;
25633 case LOADINFOSHOPV:
25634 FFScript::do_loadinfoshopdata(true);
25635 break;
25636 case LOADNPCDATAR:
25637 6366 FFScript::do_loadnpcdata(false);
25638 6366 break;
25639 case LOADNPCDATAV:
25640 FFScript::do_loadnpcdata(true);
25641 break;
25642
25643 case LOADCOMBODATAR:
25644 6042586 FFScript::do_loadcombodata(false);
25645 6042586 break;
25646 case LOADCOMBODATAV:
25647 FFScript::do_loadcombodata(true);
25648 break;
25649
25650 case LOADTMPSCR:
25651 3585254 FFScript::do_loadmapdata_tempscr(false);
25652 3585254 break;
25653 case LOADTMPSCR2:
25654 FFScript::do_loadmapdata_tempscr2(false);
25655 break;
25656 case REGION_LOAD_TMPSCR_FOR_LAYER_COMBO_POS:
25657 do_loadtmpscrforcombopos(false);
25658 break;
25659 case LOADSCROLLSCR:
25660 182518 FFScript::do_loadmapdata_scrollscr(false);
25661 182518 break;
25662 case LOADSCROLLSCR2:
25663 FFScript::do_loadmapdata_scrollscr2(false);
25664 break;
25665
25666 case LOADSPRITEDATAR:
25667 5603 FFScript::do_loadspritedata(false);
25668 5603 break;
25669 case LOADSPRITEDATAV:
25670 FFScript::do_loadspritedata(true);
25671 break;
25672
25673 case LOADBITMAPDATAR:
25674 10 FFScript::do_loadbitmapid(false);
25675 10 break;
25676
25677
25678 case LOADBITMAPDATAV:
25679 FFScript::do_loadbitmapid(true);
25680 break;
25681
25682 //functions
25683 case CREATEPALDATA:
25684 223 FFCore.do_create_paldata(); break;
25685 case CREATEPALDATACLR:
25686 11 FFCore.do_create_paldata_clr(); break;
25687 case MIXCLR:
25688 FFCore.do_mix_clr(); break;
25689 case CREATERGBHEX:
25690 FFCore.do_create_rgb_hex(); break;
25691 case CREATERGB:
25692 11 FFCore.do_create_rgb(); break;
25693 case CONVERTFROMRGB:
25694 FFCore.do_convert_from_rgb(); break;
25695 case CONVERTTORGB:
25696 FFCore.do_convert_to_rgb(); break;
25697 case PALDATALOADLEVEL:
25698 24 FFCore.do_paldata_load_level(); break;
25699 case PALDATALOADSPRITE:
25700 87 FFCore.do_paldata_load_sprite(); break;
25701 case PALDATALOADMAIN:
25702 92 FFCore.do_paldata_load_main(); break;
25703 case PALDATALOADCYCLE:
25704 FFCore.do_paldata_load_cycle(); break;
25705 case PALDATALOADBITMAP:
25706 FFCore.do_paldata_load_bitmap(); break;
25707 case PALDATAWRITELEVEL:
25708 370 FFCore.do_paldata_write_level(); break;
25709 case PALDATAWRITELEVELCS:
25710 FFCore.do_paldata_write_levelcset(); break;
25711 case PALDATAWRITESPRITE:
25712 31 FFCore.do_paldata_write_sprite(); break;
25713 case PALDATAWRITESPRITECS:
25714 FFCore.do_paldata_write_spritecset(); break;
25715 case PALDATAWRITEMAIN:
25716 1064 FFCore.do_paldata_write_main(); break;
25717 case PALDATAWRITEMAINCS:
25718 130 FFCore.do_paldata_write_maincset(); break;
25719 case PALDATAWRITECYCLE:
25720 FFCore.do_paldata_write_cycle(); break;
25721 case PALDATAWRITECYCLECS:
25722 FFCore.do_paldata_write_cyclecset(); break;
25723 case PALDATAVALIDCLR:
25724 FFCore.do_paldata_colorvalid(); break;
25725 case PALDATACLEARCLR:
25726 FFCore.do_paldata_clearcolor(); break;
25727 case PALDATACLEARCSET:
25728 FFCore.do_paldata_clearcset(); break;
25729 case PALDATAMIX:
25730 450 FFCore.do_paldata_mix(); break;
25731 case PALDATAMIXCS:
25732 4781 FFCore.do_paldata_mixcset(); break;
25733 case PALDATACOPY:
25734 FFCore.do_paldata_copy(); break;
25735 case PALDATACOPYCSET:
25736 112 FFCore.do_paldata_copycset(); break;
25737 case PALDATAFREE:
25738
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 234 times.
234 if (user_paldata* pd = checkPalData(GET_REF(paldataref), true))
25739 {
25740 234 free_script_object(pd->id);
25741 234 }
25742 234 break;
25743 case PALDATAOWN:
25744 if (user_paldata* pd = checkPalData(GET_REF(paldataref), false))
25745 {
25746 own_script_object(pd, type, i);
25747 }
25748 break;
25749 case LOADRNG: //command
25750 932 FFCore.do_loadrng(); break;
25751
25752 case ITEMGETDISPLAYNAME: //command
25753 53 item_display_name(false); break;
25754 case ITEMSETDISPLAYNAME: //command
25755 item_display_name(true); break;
25756 case ITEMGETSHOWNNAME: //command
25757 item_shown_name(); break;
25758
25759 case DMAPDATAGETNAMER: //command
25760 FFScript::do_getDMapData_dmapname(false); break;
25761 case DMAPDATAGETNAMEV: //command
25762 FFScript::do_getDMapData_dmapname(true); break;
25763
25764 case DMAPDATASETNAMER: //command
25765 FFScript::do_setDMapData_dmapname(false); break;
25766 case DMAPDATASETNAMEV: //command
25767 FFScript::do_setDMapData_dmapname(true); break;
25768
25769
25770
25771 case DMAPDATAGETTITLER: //command
25772 FFScript::do_getDMapData_dmaptitle(false); break;
25773 case DMAPDATAGETTITLEV: //command
25774 FFScript::do_getDMapData_dmaptitle(true); break;
25775 case DMAPDATASETTITLER: //command
25776 FFScript::do_setDMapData_dmaptitle(false); break;
25777 case DMAPDATASETTITLEV: //command
25778 FFScript::do_setDMapData_dmaptitle(true); break;
25779
25780
25781 case DMAPDATAGETINTROR: //command
25782 FFScript::do_getDMapData_dmapintro(false); break;
25783 case DMAPDATAGETINTROV: //command
25784 FFScript::do_getDMapData_dmapintro(true); break;
25785 case DMAPDATANSETITROR: //command
25786 FFScript::do_setDMapData_dmapintro(false); break;
25787 case DMAPDATASETINTROV: //command
25788 FFScript::do_setDMapData_dmapintro(true); break;
25789
25790
25791 case DMAPDATAGETMUSICR: //command, string to load a music file
25792 14 FFScript::do_getDMapData_music(false); break;
25793 case DMAPDATAGETMUSICV: //command, string to load a music file
25794 FFScript::do_getDMapData_music(true); break;
25795 case DMAPDATASETMUSICR: //command, string to load a music file
25796 FFScript::do_setDMapData_music(false); break;
25797 case DMAPDATASETMUSICV: //command, string to load a music file
25798 FFScript::do_setDMapData_music(true); break;
25799
25800 case LOADMESSAGEDATAR: //COMMAND
25801 54 FFScript::do_loadmessagedata(false);
25802 54 break;
25803 case LOADMESSAGEDATAV: //COMMAND
25804 FFScript::do_loadmessagedata(false);
25805 break;
25806
25807
25808 case MESSAGEDATASETSTRINGR: //command
25809 52 FFScript::do_messagedata_setstring(false);
25810 52 break;
25811 case MESSAGEDATASETSTRINGV: //command
25812 FFScript::do_messagedata_setstring(false);
25813 break;
25814
25815 case MESSAGEDATAGETSTRINGR: //command
25816 18 FFScript::do_messagedata_getstring(false);
25817 18 break;
25818 case MESSAGEDATAGETSTRINGV: //command
25819 FFScript::do_messagedata_getstring(false);
25820 break;
25821 case LOADITEMDATAV:
25822 do_loaditemdata(true);
25823 break;
25824
25825 case LOADNPCBYSUID:
25826 12 FFCore.do_loadnpc_by_script_uid(false);
25827 12 break;
25828
25829 case LOADLWEAPONBYSUID:
25830 598 FFCore.do_loadlweapon_by_script_uid(false);
25831 598 break;
25832
25833 case LOADWEAPONCBYSUID:
25834 FFCore.do_loadeweapon_by_script_uid(false);
25835 break;
25836
25837 case LOADNPCR:
25838 32179030 do_loadnpc(false);
25839 32179030 break;
25840
25841 case LOADNPCV:
25842 do_loadnpc(true);
25843 break;
25844
25845 case CREATELWEAPONR:
25846 166704 do_createlweapon(false);
25847 166704 break;
25848
25849 case CREATELWEAPONV:
25850 do_createlweapon(true);
25851 break;
25852
25853 case CREATEEWEAPONR:
25854 303017 do_createeweapon(false);
25855 303017 break;
25856
25857 case CREATEEWEAPONV:
25858 do_createeweapon(true);
25859 break;
25860
25861 case CREATEITEMR:
25862 22558 do_createitem(false);
25863 22558 break;
25864
25865 case CREATEITEMV:
25866 do_createitem(true);
25867 break;
25868
25869 case CREATENPCR:
25870 3595 do_createnpc(false);
25871 3595 break;
25872
25873 case CREATENPCV:
25874 do_createnpc(true);
25875 break;
25876
25877 case ISVALIDARRAY:
25878 601509 do_isvalidarray();
25879 601509 break;
25880
25881 case ISVALIDITEM:
25882 31517 do_isvaliditem();
25883 31517 break;
25884
25885 case ISVALIDBITMAP:
25886 8420 FFCore.do_isvalidbitmap();
25887 8420 break;
25888
25889 case ISALLOCATEDBITMAP:
25890 117 FFCore.do_isallocatedbitmap();
25891 117 break;
25892
25893 case ISVALIDNPC:
25894 11796078 do_isvalidnpc();
25895 11796078 break;
25896
25897 case ISVALIDLWPN:
25898 1279180 do_isvalidlwpn();
25899 1279180 break;
25900
25901 case ISVALIDEWPN:
25902 176099 do_isvalidewpn();
25903 176099 break;
25904
25905 case LWPNMAKEANGULAR:
25906 do_lwpnmakeangular();
25907 break;
25908
25909 case EWPNMAKEANGULAR:
25910 do_ewpnmakeangular();
25911 break;
25912
25913 case LWPNMAKEDIRECTIONAL:
25914 do_lwpnmakedirectional();
25915 break;
25916
25917 case EWPNMAKEDIRECTIONAL:
25918 do_ewpnmakedirectional();
25919 break;
25920
25921 case LWPNUSESPRITER:
25922 20064 do_lwpnusesprite(false);
25923 20064 break;
25924
25925 case LWPNUSESPRITEV:
25926 do_lwpnusesprite(true);
25927 break;
25928
25929 case EWPNUSESPRITER:
25930 296065 do_ewpnusesprite(false);
25931 296065 break;
25932
25933 case EWPNUSESPRITEV:
25934 do_ewpnusesprite(true);
25935 break;
25936
25937 case CLEARSPRITESR:
25938 do_clearsprites(false);
25939 break;
25940
25941 case CLEARSPRITESV:
25942 do_clearsprites(true);
25943 break;
25944
25945 case ISSOLID:
25946 25461489 do_issolid();
25947 25461489 break;
25948
25949 case MAPDATAISSOLID:
25950 do_mapdataissolid();
25951 break;
25952
25953 case MAPDATAISSOLIDLYR:
25954 do_mapdataissolid_layer();
25955 break;
25956
25957 case ISSOLIDLAYER:
25958 do_issolid_layer();
25959 break;
25960
25961 case SETSIDEWARP:
25962 257 do_setsidewarp();
25963 257 break;
25964
25965 case SETTILEWARP:
25966 5 do_settilewarp();
25967 5 break;
25968
25969 case GETSIDEWARPDMAP:
25970 364895 do_getsidewarpdmap(false);
25971 364895 break;
25972
25973 case GETSIDEWARPSCR:
25974 3 do_getsidewarpscr(false);
25975 3 break;
25976
25977 case GETSIDEWARPTYPE:
25978 do_getsidewarptype(false);
25979 break;
25980
25981 case GETTILEWARPDMAP:
25982 364942 do_gettilewarpdmap(false);
25983 364942 break;
25984
25985 case GETTILEWARPSCR:
25986 50 do_gettilewarpscr(false);
25987 50 break;
25988
25989 case GETTILEWARPTYPE:
25990 3 do_gettilewarptype(false);
25991 3 break;
25992
25993 case LAYERSCREEN:
25994 13670631 do_layerscreen();
25995 13670631 break;
25996
25997 case LAYERMAP:
25998 18282859 do_layermap();
25999 18282859 break;
26000
26001 case SECRETS:
26002 382 do_triggersecrets(GET_REF(screenref));
26003 382 break;
26004
26005 case REGION_TRIGGER_SECRETS:
26006 {
26007 118 int screen = get_register(sarg1) / 10000;
26008
1/2
✓ Branch 0 taken 118 times.
✗ Branch 1 not taken.
118 if (!is_in_current_region(screen))
26009 {
26010 scripting_log_error_with_context("Must use a screen in the current region. got: {}", screen);
26011 break;
26012 }
26013
26014 118 do_triggersecrets(screen);
26015 118 break;
26016 }
26017
26018 case GRAPHICSGETPIXEL:
26019 FFCore.do_graphics_getpixel();
26020 break;
26021 case GRAPHICSCOUNTCOLOR:
26022 FFCore.do_bmpcollision();
26023 break;
26024
26025 case COMBOTILE:
26026 3182 do_combotile(false);
26027 3182 break;
26028
26029 case DRAWLIGHT_CIRCLE:
26030 {
26031 if (get_qr(qr_SCRIPTS_SCREEN_DRAW_LIGHT_NO_OFFSET))
26032 {
26033 static const int ARGS = 7;
26034 zfix cx = zslongToFix(SH::read_stack(ri->sp + (ARGS-1)));
26035 zfix cy = zslongToFix(SH::read_stack(ri->sp + (ARGS-2)));
26036 int radius = SH::read_stack(ri->sp + (ARGS-3));
26037 int transp_rad = SH::read_stack(ri->sp + (ARGS-4));
26038 int dith_rad = SH::read_stack(ri->sp + (ARGS-5));
26039 int dith_type = SH::read_stack(ri->sp + (ARGS-6));
26040 int dith_arg = SH::read_stack(ri->sp + (ARGS-7));
26041 if(radius >= 0) radius /= 10000;
26042 else radius = game->get_light_rad();
26043 if(!radius) break;
26044 if(transp_rad >= 0) transp_rad /= 10000;
26045 if(dith_rad >= 0) dith_rad /= 10000;
26046 if(dith_type >= 0) dith_type /= 10000;
26047 if(dith_arg >= 0) dith_arg /= 10000;
26048
26049 doDarkroomCircle(cx,cy,radius,darkscr_bmp,nullptr,dith_rad,transp_rad,dith_type,dith_arg);
26050 }
26051 else do_drawing_command(scommand, true);
26052
26053 break;
26054 }
26055 case DRAWLIGHT_SQUARE:
26056 {
26057 if (get_qr(qr_SCRIPTS_SCREEN_DRAW_LIGHT_NO_OFFSET))
26058 {
26059 static const int ARGS = 7;
26060 zfix cx = zslongToFix(SH::read_stack(ri->sp + (ARGS-1)));
26061 zfix cy = zslongToFix(SH::read_stack(ri->sp + (ARGS-2)));
26062 int radius = SH::read_stack(ri->sp + (ARGS-3));
26063 int transp_rad = SH::read_stack(ri->sp + (ARGS-4));
26064 int dith_rad = SH::read_stack(ri->sp + (ARGS-5));
26065 int dith_type = SH::read_stack(ri->sp + (ARGS-6));
26066 int dith_arg = SH::read_stack(ri->sp + (ARGS-7));
26067 if(radius >= 0) radius /= 10000;
26068 else radius = game->get_light_rad();
26069 if(!radius) break;
26070 if(transp_rad >= 0) transp_rad /= 10000;
26071 if(dith_rad >= 0) dith_rad /= 10000;
26072 if(dith_type >= 0) dith_type /= 10000;
26073 if(dith_arg >= 0) dith_arg /= 10000;
26074
26075 doDarkroomSquare(cx,cy,radius,darkscr_bmp,nullptr,dith_rad,transp_rad,dith_type,dith_arg);
26076 }
26077 else do_drawing_command(scommand, true);
26078
26079 break;
26080 }
26081 case DRAWLIGHT_CONE:
26082 {
26083 if (get_qr(qr_SCRIPTS_SCREEN_DRAW_LIGHT_NO_OFFSET))
26084 {
26085 static const int ARGS = 8;
26086 zfix cx = zslongToFix(SH::read_stack(ri->sp + (ARGS-1)));
26087 zfix cy = zslongToFix(SH::read_stack(ri->sp + (ARGS-2)));
26088 int dir = SH::read_stack(ri->sp + (ARGS-3)) / 10000;
26089 int length = SH::read_stack(ri->sp + (ARGS-4));
26090 int transp_rad = SH::read_stack(ri->sp + (ARGS-5));
26091 int dith_rad = SH::read_stack(ri->sp + (ARGS-6));
26092 int dith_type = SH::read_stack(ri->sp + (ARGS-7));
26093 int dith_arg = SH::read_stack(ri->sp + (ARGS-8));
26094 if(length >= 0) length /= 10000;
26095 else length = game->get_light_rad()*2;
26096 if(!length) break;
26097 if(dir < 0) break;
26098 else dir = NORMAL_DIR(dir);
26099 if(transp_rad >= 0) transp_rad /= 10000;
26100 if(dith_rad >= 0) dith_rad /= 10000;
26101 if(dith_type >= 0) dith_type /= 10000;
26102 if(dith_arg >= 0) dith_arg /= 10000;
26103
26104 doDarkroomCone(cx,cy,length,dir,darkscr_bmp,nullptr,dith_rad,transp_rad,dith_type,dith_arg);
26105 }
26106 else do_drawing_command(scommand, true);
26107
26108 break;
26109 }
26110
26111 case RECTR:
26112 case CIRCLER:
26113 case ARCR:
26114 case ELLIPSER:
26115 case LINER:
26116 case PUTPIXELR:
26117 case PIXELARRAYR:
26118 case TILEARRAYR:
26119 case LINESARRAY:
26120 case COMBOARRAYR:
26121 case DRAWTILER:
26122 case DRAWTILECLOAKEDR:
26123 case DRAWCOMBOR:
26124 case DRAWCOMBOCLOAKEDR:
26125 case DRAWCHARR:
26126 case DRAWINTR:
26127 case QUADR:
26128 case TRIANGLER:
26129 case QUAD3DR:
26130 case TRIANGLE3DR:
26131 case FASTTILER:
26132 case FASTCOMBOR:
26133 case DRAWSTRINGR:
26134 case DRAWSTRINGR2:
26135 case BMPDRAWSTRINGR2:
26136 case SPLINER:
26137 case BITMAPR:
26138 case BITMAPEXR:
26139 case DRAWLAYERR:
26140 case DRAWSCREENR:
26141 case POLYGONR:
26142 case FRAMER:
26143 case TILEBLIT:
26144 case COMBOBLIT:
26145 53527326 do_drawing_command(scommand, true);
26146 53527326 break;
26147
26148 case BMPRECTR:
26149 case BMPCIRCLER:
26150 case BMPARCR:
26151 case BMPELLIPSER:
26152 case BMPLINER:
26153 case BMPSPLINER:
26154 case BMPPUTPIXELR:
26155 case BMPDRAWTILER:
26156 case BMPDRAWTILECLOAKEDR:
26157 case BMPDRAWCOMBOR:
26158 case BMPDRAWCOMBOCLOAKEDR:
26159 case BMPFASTTILER:
26160 case BMPFASTCOMBOR:
26161 case BMPDRAWCHARR:
26162 case BMPDRAWINTR:
26163 case BMPDRAWSTRINGR:
26164 case BMPQUADR:
26165 case BMPQUAD3DR:
26166 case BMPTRIANGLER:
26167 case BMPTRIANGLE3DR:
26168 case BMPPOLYGONR:
26169 case BMPDRAWLAYERR:
26170 case BMPDRAWLAYERSOLIDR:
26171 case BMPDRAWLAYERCFLAGR:
26172 case BMPDRAWLAYERCTYPER:
26173 case BMPDRAWLAYERCIFLAGR:
26174 case BMPDRAWLAYERSOLIDITYR:
26175 case BMPDRAWSCREENR:
26176 case BMPDRAWSCREENSOLIDR:
26177 case BMPDRAWSCREENSOLID2R:
26178 case BMPDRAWSCREENCOMBOFR:
26179 case BMPDRAWSCREENCOMBOIR:
26180 case BMPDRAWSCREENCOMBOTR:
26181 case BMPBLIT:
26182 case BMPBLITTO:
26183 case BMPTILEBLIT:
26184 case BMPCOMBOBLIT:
26185 case BMPMODE7:
26186 case WRITEBITMAP:
26187 case CLEARBITMAP:
26188 case BITMAPCLEARTOCOLOR:
26189 case BMPFRAMER:
26190 case BMPWRITETILE:
26191 case BMPDITHER:
26192 case BMPREPLCOLOR:
26193 case BMPSHIFTCOLOR:
26194 case BMPMASKDRAW:
26195 case BMPMASKDRAW2:
26196 case BMPMASKDRAW3:
26197 case BMPMASKBLIT:
26198 case BMPMASKBLIT2:
26199 case BMPMASKBLIT3:
26200 65124359 do_drawing_command(scommand, false);
26201 65124359 break;
26202 case READBITMAP:
26203 {
26204 uint32_t bitref = SH::read_stack(ri->sp+2);
26205 SET_D(rEXP2, bitref);
26206 if(user_bitmap* b = checkBitmap(bitref,false,true))
26207 do_drawing_command(scommand, false);
26208 else //If the pointer isn't allocated, attempt to allocate it first
26209 {
26210 bitref = FFCore.get_free_bitmap();
26211 SET_D(rEXP2, bitref); //Return to ptr
26212 if(bitref) SH::write_stack(ri->sp+2,bitref); //Write the ref, for the drawing command to read
26213 else break; //No ref allocated; don't enqueue the drawing command.
26214 do_drawing_command(scommand, false);
26215 }
26216 break;
26217 }
26218 case REGENERATEBITMAP:
26219 {
26220 26757 int ref = SH::read_stack(ri->sp+3);
26221 26757 SET_D(rEXP2, ref);
26222
1/2
✓ Branch 0 taken 26757 times.
✗ Branch 1 not taken.
26757 if(user_bitmap* b = checkBitmap(ref,false,true))
26223 26757 do_drawing_command(scommand, false);
26224 else //If the pointer isn't allocated
26225 {
26226 int32_t w = SH::read_stack(ri->sp) / 10000;
26227 int32_t h = SH::read_stack(ri->sp+1) / 10000;
26228 if ( get_qr(qr_OLDCREATEBITMAP_ARGS) )
26229 {
26230 //flip height and width
26231 h = h ^ w;
26232 w = h ^ w;
26233 h = h ^ w;
26234 }
26235
26236 SET_D(rEXP2, FFCore.create_user_bitmap_ex(h,w)); //Return to ptr
26237 }
26238 26757 break;
26239 }
26240
26241 case BITMAPFREE:
26242 {
26243 3512 FFCore.do_deallocate_bitmap();
26244 3512 break;
26245 }
26246
26247 case BITMAPOWN:
26248 {
26249
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 146 times.
146 if(FFCore.isSystemBitref(GET_REF(bitmapref)))
26250 break; //Don't attempt to own system bitmaps!
26251
26252
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 146 times.
146 if (auto bitmap = checkBitmap(GET_REF(bitmapref), false))
26253 146 own_script_object(bitmap, type, i);
26254 146 break;
26255 }
26256
26257 case OBJ_OWN_BITMAP:
26258 {
26259 int bmpid = get_register(sarg1);
26260 if(FFCore.isSystemBitref(bmpid))
26261 break; //Don't attempt to own system bitmaps!
26262 user_bitmap* b = checkBitmap(bmpid, false);
26263 if(!b) break;
26264 ScriptType own_type = (ScriptType)sarg2;
26265 sprite* own_sprite = get_own_sprite(own_type);
26266 own_script_object(b, own_sprite);
26267 break;
26268 }
26269 case OBJ_OWN_PALDATA:
26270 {
26271 int palid = get_register(sarg1);
26272 user_paldata* pd = checkPalData(palid, false);
26273 if(!pd) break;
26274 ScriptType own_type = (ScriptType)sarg2;
26275 sprite* own_sprite = get_own_sprite(own_type);
26276 own_script_object(pd, own_sprite);
26277 break;
26278 }
26279 case OBJ_OWN_FILE:
26280 {
26281 int fileid = get_register(sarg1);
26282 user_file* f = checkFile(fileid, false);
26283 if(!f) break;
26284 ScriptType own_type = (ScriptType)sarg2;
26285 sprite* own_sprite = get_own_sprite(own_type);
26286 own_script_object(f, own_sprite);
26287 break;
26288 }
26289 case OBJ_OWN_DIR:
26290 {
26291 int dirid = get_register(sarg1);
26292 user_dir* dr = checkDir(dirid, false);
26293 if(!dr) break;
26294 ScriptType own_type = (ScriptType)sarg2;
26295 sprite* own_sprite = get_own_sprite(own_type);
26296 own_script_object(dr, own_sprite);
26297 break;
26298 }
26299 case OBJ_OWN_STACK:
26300 {
26301 int stackid = get_register(sarg1);
26302 user_stack* st = checkStack(stackid, false);
26303 if(!st) break;
26304 ScriptType own_type = (ScriptType)sarg2;
26305 sprite* own_sprite = get_own_sprite(own_type);
26306 own_script_object(st, own_sprite);
26307 break;
26308 }
26309 case OBJ_OWN_RNG:
26310 {
26311 int rngid = get_register(sarg1);
26312 user_rng* r = checkRNG(rngid, false);
26313 if(!r) break;
26314 ScriptType own_type = (ScriptType)sarg2;
26315 sprite* own_sprite = get_own_sprite(own_type);
26316 own_script_object(r, own_sprite);
26317 break;
26318 }
26319 case OBJ_OWN_ARRAY:
26320 {
26321 int arrid = get_register(sarg1);
26322 ScriptType own_type = (ScriptType)sarg2;
26323 sprite* own_sprite = get_own_sprite(own_type);
26324 do_own_array(arrid, own_sprite);
26325 break;
26326 }
26327
26328 case COPYTILEVV:
26329 do_copytile(true, true);
26330 break;
26331
26332 case COPYTILEVR:
26333 do_copytile(true, false);
26334 break;
26335
26336 case COPYTILERV:
26337 do_copytile(false, true);
26338 break;
26339
26340 case COPYTILERR:
26341 49289145 do_copytile(false, false);
26342 49289145 break;
26343
26344 case SWAPTILEVV:
26345 do_swaptile(true, true);
26346 break;
26347
26348 case SWAPTILEVR:
26349 do_swaptile(true, false);
26350 break;
26351
26352 case SWAPTILERV:
26353 do_swaptile(false, true);
26354 break;
26355
26356 case SWAPTILERR:
26357 do_swaptile(false, false);
26358 break;
26359
26360 case CLEARTILEV:
26361 do_cleartile(true);
26362 break;
26363
26364 case CLEARTILER:
26365 10 do_cleartile(false);
26366 10 break;
26367
26368 case OVERLAYTILEVV:
26369 do_overlaytile(true, true);
26370 break;
26371
26372 case OVERLAYTILEVR:
26373 do_overlaytile(true, false);
26374 break;
26375
26376 case OVERLAYTILERV:
26377 do_overlaytile(false, true);
26378 break;
26379
26380 case OVERLAYTILERR:
26381 57032 do_overlaytile(false, false);
26382 57032 break;
26383
26384 case FLIPROTTILEVV:
26385 do_fliprotatetile(true, true);
26386 break;
26387
26388 case FLIPROTTILEVR:
26389 do_fliprotatetile(true, false);
26390 break;
26391
26392 case FLIPROTTILERV:
26393 do_fliprotatetile(false, true);
26394 break;
26395
26396 case FLIPROTTILERR:
26397 do_fliprotatetile(false, false);
26398 break;
26399
26400 case GETTILEPIXEL:
26401 do_gettilepixel();
26402 break;
26403
26404 case SETTILEPIXEL:
26405 do_settilepixel();
26406 break;
26407
26408 case SHIFTTILEVV:
26409 do_shifttile(true, true);
26410 break;
26411
26412 case SHIFTTILEVR:
26413 do_shifttile(true, false);
26414 break;
26415
26416 case SHIFTTILERV:
26417 do_shifttile(false, true);
26418 break;
26419
26420 case SHIFTTILERR:
26421 do_shifttile(false, false);
26422 break;
26423
26424 case SETRENDERTARGET:
26425 7084216 do_set_rendertarget(true);
26426 7084216 break;
26427
26428 case GAMEEND:
26429
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if ( using_SRAM )
26430 {
26431 Z_scripterrlog("Cannot End Game while reading or writing to SRAM. Aborting End. /n");
26432 break;
26433 }
26434 4 Quit = qQUIT;
26435 4 skipcont = 1;
26436 4 scommand = 0xFFFF;
26437 4 break;
26438 case GAMEEXIT:
26439 42 Quit = qEXIT;
26440 42 skipcont = 1;
26441 42 scommand = 0xFFFF;
26442 42 break;
26443 case GAMERELOAD:
26444
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if ( using_SRAM )
26445 {
26446 Z_scripterrlog("Cannot Reload Game while reading or writing to SRAM. Aborting Reload. /n");
26447 break;
26448 }
26449 9 Quit = qRELOAD;
26450 9 skipcont = 1;
26451 9 scommand = 0xFFFF;
26452 9 break;
26453 case GAMESETCUSTOMCURSOR:
26454 {
26455 int32_t bmpptr = SH::read_stack(ri->sp + 4);
26456 int fx = SH::read_stack(ri->sp + 3) / 10000;
26457 int fy = SH::read_stack(ri->sp + 2) / 10000;
26458 bool recolor = SH::read_stack(ri->sp + 1)!=0;
26459 bool scale = SH::read_stack(ri->sp + 0)!=0;
26460 if(user_bitmap* b = checkBitmap(bmpptr,true))
26461 {
26462 custom_mouse(b->u_bmp,fx,fy,recolor,scale);
26463 }
26464 break;
26465 }
26466 case CURRENTITEMID:
26467 {
26468 11953 int ity = SH::read_stack(ri->sp + 1) / 10000;
26469 11953 int flags = SH::read_stack(ri->sp + 0) / 10000;
26470 11953 bool checkcost = flags&0x01;
26471 11953 bool checkjinx = flags&0x02;
26472 11953 bool check_bunny = flags&0x04;
26473 11953 SET_D(rEXP1, current_item_id(ity,checkcost,checkjinx,check_bunny) * 10000);
26474 11953 break;
26475 }
26476
26477 case GAMECONTINUE:
26478
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if ( using_SRAM )
26479 {
26480 Z_scripterrlog("Cannot Continue Game while reading or writing to SRAM. Aborting Continue. /n");
26481 break;
26482 }
26483 2 reset_all_combo_animations();
26484
26485 2 Quit = qCONT;
26486 2 skipcont = 1;
26487 //cont_game();
26488 2 scommand = 0xFFFF;
26489 2 break;
26490
26491 case GAMESAVEQUIT:
26492 if ( using_SRAM )
26493 {
26494 Z_scripterrlog("Cannot Save Game while reading or writing to SRAM. Aborting Save. /n");
26495 break;
26496 }
26497 Quit = qSAVE;
26498 skipcont = 1;
26499 scommand =0xFFFF;
26500 break;
26501
26502 case GAMESAVECONTINUE:
26503 Quit = qSAVECONT;
26504 skipcont = 1;
26505 scommand =0xFFFF;
26506 break;
26507
26508 case SAVE:
26509
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if ( using_SRAM )
26510 {
26511 Z_scripterrlog("Cannot Save Game while reading or writing to SRAM. Aborting Save. /n");
26512 break;
26513 }
26514
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if(scriptCanSave)
26515 {
26516 30 save_game(false);
26517 30 scriptCanSave=false;
26518 30 }
26519 30 break;
26520
26521 case SAVESCREEN:
26522 do_showsavescreen();
26523 break;
26524
26525 case SHOWF6SCREEN:
26526 onTryQuit();
26527 break;
26528
26529 case SAVEQUITSCREEN:
26530 save_game(false, 1);
26531 break;
26532
26533 //Not Implemented
26534 case ELLIPSE2:
26535 case FLOODFILL:
26536 break;
26537
26538 //Visual Effects
26539 case WAVYIN:
26540 FFScript::do_wavyin();
26541 break;
26542 case WAVYOUT:
26543 FFScript::do_wavyout();
26544 break;
26545 case ZAPIN:
26546 FFScript::do_zapin();
26547 break;
26548 case ZAPOUT:
26549 FFScript::do_zapout();
26550 break;
26551 case OPENWIPE:
26552 {
26553 FFScript::do_openscreen();
26554 break;
26555 }
26556 case CLOSEWIPE:
26557 {
26558 FFScript::do_closescreen();
26559 break;
26560 }
26561 case OPENWIPESHAPE:
26562 {
26563 FFScript::do_openscreenshape();
26564 break;
26565 }
26566 case CLOSEWIPESHAPE:
26567 {
26568 FFScript::do_closescreenshape();
26569 break;
26570 }
26571
26572 case TINT:
26573 {
26574 3560 FFCore.Tint();
26575 3560 break;
26576 }
26577
26578 case CLEARTINT:
26579 {
26580 66 FFCore.clearTint();
26581 66 break;
26582 }
26583
26584 case MONOHUE:
26585 {
26586 FFCore.gfxmonohue();
26587 break;
26588 }
26589
26590 case SCREENDOSPAWN:
26591 {
26592 14 SET_D(rEXP1, scriptloadenemies(GET_REF(screenref)) ? 10000 : 0);
26593 14 break;
26594 }
26595
26596 case SCRTRIGGERCOMBO:
26597 {
26598 int32_t lyr = get_register(sarg1) / 10000;
26599 int32_t pos = get_register(sarg2) / 10000;
26600 rpos_t rpos = (rpos_t)pos;
26601 if (BC::checkComboRpos(rpos) != SH::_NoError)
26602 {
26603 break;
26604 }
26605
26606 set_register(sarg1, do_trigger_combo(get_rpos_handle(rpos, lyr), 0) ? 10000 : 0);
26607 break;
26608 }
26609 case SCRTRIGGERCOMBO2:
26610 {
26611 int32_t lyr = get_register(sarg1) / 10000;
26612 int32_t pos = get_register(sarg2) / 10000;
26613 int32_t idx = get_register(sarg3) / 10000;
26614 rpos_t rpos = (rpos_t)pos;
26615 if (BC::checkComboRpos(rpos) != SH::_NoError)
26616 break;
26617
26618 set_register(sarg1, do_trigger_combo(get_rpos_handle(rpos, lyr), idx) ? 10000 : 0);
26619 break;
26620 }
26621
26622 case SWITCHNPC:
26623 {
26624 byte effect = vbound(get_register(sarg1)/10000, 0, 255);
26625 set_register(sarg1,0);
26626 if(Hero.switchhookclk) break; //Already switching!
26627 if(GuyH::loadNPC(GET_REF(npcref)) == SH::_NoError)
26628 {
26629 switching_object = guys.getByUID(GET_REF(npcref));
26630 hooked_comborpos = rpos_t::None;
26631 hooked_layerbits = 0;
26632 switching_object->switch_hooked = true;
26633 Hero.doSwitchHook(effect);
26634 set_register(sarg1,10000);
26635 }
26636 break;
26637 }
26638
26639 case SWITCHITM:
26640 {
26641 byte effect = vbound(get_register(sarg1)/10000, 0, 255);
26642 set_register(sarg1,0);
26643 if(Hero.switchhookclk) break; //Already switching!
26644 if(ItemH::loadItem(GET_REF(itemref)) == SH::_NoError)
26645 {
26646 switching_object = ItemH::getItem();
26647 hooked_comborpos = rpos_t::None;
26648 hooked_layerbits = 0;
26649 switching_object->switch_hooked = true;
26650 Hero.doSwitchHook(effect);
26651 set_register(sarg1,10000);
26652 }
26653 break;
26654 }
26655
26656 case SWITCHLW:
26657 {
26658 byte effect = vbound(get_register(sarg1)/10000, 0, 255);
26659 set_register(sarg1,0);
26660 if(Hero.switchhookclk) break; //Already switching!
26661 if(LwpnH::loadWeapon(GET_REF(lwpnref)) == SH::_NoError)
26662 {
26663 switching_object = LwpnH::getWeapon();
26664 hooked_comborpos = rpos_t::None;
26665 hooked_layerbits = 0;
26666 switching_object->switch_hooked = true;
26667 Hero.doSwitchHook(effect);
26668 set_register(sarg1,10000);
26669 }
26670 break;
26671 }
26672
26673 case SWITCHEW:
26674 {
26675 byte effect = vbound(get_register(sarg1)/10000, 0, 255);
26676 set_register(sarg1,0);
26677 if(Hero.switchhookclk) break; //Already switching!
26678 if(EwpnH::loadWeapon(GET_REF(ewpnref)) == SH::_NoError)
26679 {
26680 switching_object = EwpnH::getWeapon();
26681 hooked_comborpos = rpos_t::None;
26682 hooked_layerbits = 0;
26683 switching_object->switch_hooked = true;
26684 Hero.doSwitchHook(effect);
26685 set_register(sarg1,10000);
26686 }
26687 break;
26688 }
26689
26690 case SWITCHCMB:
26691 {
26692 rpos_t rpos = (rpos_t)(get_register(sarg1)/10000);
26693 set_register(sarg1,0);
26694 if(Hero.switchhookclk) break; //Already switching!
26695 if (!is_valid_rpos(rpos))
26696 break;
26697 switching_object = NULL;
26698 hooked_comborpos = rpos;
26699 hooked_layerbits = 0;
26700 Hero.doSwitchHook(get_register(sarg2)/10000);
26701 if(!hooked_layerbits) //failed
26702 Hero.reset_hookshot();
26703 else set_register(sarg1,10000); //success return
26704 break;
26705 }
26706
26707 case LINKWARPEXR:
26708 {
26709 100 FFCore.do_warp_ex_array();
26710 100 break;
26711 }
26712 case WARPEX:
26713 {
26714 FFCore.do_warp_ex();
26715 break;
26716 }
26717
26718 case KILLPLAYER:
26719 {
26720 Hero.kill(get_register(sarg1));
26721 break;
26722 }
26723
26724 case HEROMOVEXY:
26725 {
26726 1798 zfix dx = zslongToFix(SH::read_stack(ri->sp + 4));
26727 1798 zfix dy = zslongToFix(SH::read_stack(ri->sp + 3));
26728 1798 bool kb = SH::read_stack(ri->sp + 2)!=0;
26729 1798 bool ign_sv = SH::read_stack(ri->sp + 1)!=0;
26730 1798 bool shove = SH::read_stack(ri->sp + 0)!=0;
26731 1798 SET_D(rEXP1, Hero.movexy(dx, dy, kb, ign_sv, shove) ? 10000 : 0);
26732 1798 break;
26733 }
26734 case HEROCANMOVEXY:
26735 {
26736 3596 zfix dx = zslongToFix(SH::read_stack(ri->sp + 4));
26737 3596 zfix dy = zslongToFix(SH::read_stack(ri->sp + 3));
26738 3596 bool kb = SH::read_stack(ri->sp + 2)!=0;
26739 3596 bool ign_sv = SH::read_stack(ri->sp + 1)!=0;
26740 3596 bool shove = SH::read_stack(ri->sp + 0)!=0;
26741 3596 SET_D(rEXP1, Hero.can_movexy(dx, dy, kb, ign_sv, shove) ? 10000 : 0);
26742 3596 break;
26743 }
26744 case HEROMOVEATANGLE:
26745 {
26746 zfix degrees = zslongToFix(SH::read_stack(ri->sp + 4));
26747 zfix pxamnt = zslongToFix(SH::read_stack(ri->sp + 3));
26748 bool kb = SH::read_stack(ri->sp + 2)!=0;
26749 bool ign_sv = SH::read_stack(ri->sp + 1)!=0;
26750 bool shove = SH::read_stack(ri->sp + 0)!=0;
26751 SET_D(rEXP1, Hero.moveAtAngle(degrees, pxamnt, kb, ign_sv, shove) ? 10000 : 0);
26752 break;
26753 }
26754 case HEROCANMOVEATANGLE:
26755 {
26756 zfix degrees = zslongToFix(SH::read_stack(ri->sp + 4));
26757 zfix pxamnt = zslongToFix(SH::read_stack(ri->sp + 3));
26758 bool kb = SH::read_stack(ri->sp + 2)!=0;
26759 bool ign_sv = SH::read_stack(ri->sp + 1)!=0;
26760 bool shove = SH::read_stack(ri->sp + 0)!=0;
26761 SET_D(rEXP1, Hero.can_moveAtAngle(degrees, pxamnt, kb, ign_sv, shove) ? 10000 : 0);
26762 break;
26763 }
26764 case HEROMOVE:
26765 {
26766 int dir = SH::read_stack(ri->sp + 4)/10000;
26767 zfix pxamnt = zslongToFix(SH::read_stack(ri->sp + 3));
26768 bool kb = SH::read_stack(ri->sp + 2)!=0;
26769 bool ign_sv = SH::read_stack(ri->sp + 1)!=0;
26770 bool shove = SH::read_stack(ri->sp + 0)!=0;
26771 SET_D(rEXP1, Hero.moveDir(dir, pxamnt, kb, ign_sv, shove) ? 10000 : 0);
26772 break;
26773 }
26774 case HEROCANMOVE:
26775 {
26776 440764 int dir = SH::read_stack(ri->sp + 4)/10000;
26777 440764 zfix pxamnt = zslongToFix(SH::read_stack(ri->sp + 3));
26778 440764 bool kb = SH::read_stack(ri->sp + 2)!=0;
26779 440764 bool ign_sv = SH::read_stack(ri->sp + 1)!=0;
26780 440764 bool shove = SH::read_stack(ri->sp + 0)!=0;
26781 440764 SET_D(rEXP1, Hero.can_moveDir(dir, pxamnt, kb, ign_sv, shove) ? 10000 : 0);
26782 440764 break;
26783 }
26784 case HEROLIFTRELEASE:
26785 {
26786 if(Hero.lift_wpn)
26787 {
26788 SET_D(rEXP1, Hero.lift_wpn->getUID());
26789 Lwpns.add(Hero.lift_wpn);
26790 Hero.lift_wpn = nullptr;
26791 }
26792 else SET_D(rEXP1, 0);
26793 break;
26794 }
26795 case HEROLIFTGRAB:
26796 {
26797 auto lwuid = SH::read_stack(ri->sp + 2);
26798 auto lifttime = SH::read_stack(ri->sp + 1)/10000;
26799 auto liftheight = zslongToFix(SH::read_stack(ri->sp + 0));
26800 if(weapon* wpn = checkLWpn(lwuid))
26801 {
26802 Hero.lift(wpn, lifttime, liftheight);
26803 if(Lwpns.find(wpn) > -1)
26804 Lwpns.remove(wpn);
26805 if(type == ScriptType::Lwpn && lwuid == i)
26806 earlyretval = RUNSCRIPT_SELFREMOVE;
26807 }
26808 break;
26809 }
26810 case HEROISFLICKERFRAME:
26811 SET_D(rEXP1, Hero.is_hitflickerframe() ? 10000 : 0);
26812 break;
26813 case LOADPORTAL:
26814 {
26815 auto val = get_register(sarg1)/10000;
26816 if(val != -1)
26817 {
26818 portal* prt = (portal*)portals.spr(val);
26819 if(prt)
26820 val = prt->getUID();
26821 else
26822 {
26823 Z_scripterrlog("Tried to load invalid portal index '%d'\n", val);
26824 val = 0;
26825 }
26826 }
26827 ri->portalref = SET_D(rEXP1, val);
26828 break;
26829 }
26830 case CREATEPORTAL:
26831 {
26832 portal* p = new portal();
26833 if(portals.add(p))
26834 ri->portalref = SET_D(rEXP1, p->getUID());
26835 else
26836 {
26837 ri->portalref = SET_D(rEXP1, 0);
26838 Z_scripterrlog("Unable to create new portal! Limit reached!\n");
26839 }
26840 break;
26841 }
26842 case LOADSAVPORTAL:
26843 {
26844 auto val = get_register(sarg1)/10000;
26845 savedportal* prt = checkSavedPortal(val);
26846 ri->savportalref = SET_D(rEXP1, prt ? val : 0);
26847 break;
26848 }
26849 case CREATESAVPORTAL:
26850 {
26851 if(game->user_portals.size() >= MAX_SAVED_PORTALS)
26852 {
26853 ri->savportalref = SET_D(rEXP1, 0);
26854 Z_scripterrlog("Cannot create any more Saved Portals! Remove some first!\n");
26855 break;
26856 }
26857 savedportal& ref = game->user_portals.emplace_back();
26858 ri->savportalref = SET_D(rEXP1, ref.getUID());
26859 break;
26860 }
26861 case PORTALREMOVE:
26862 {
26863 if(portal* p = checkPortal(GET_REF(portalref), true))
26864 {
26865 if(p == &mirror_portal)
26866 p->clear();
26867 else
26868 {
26869 auto id = portals.find(p);
26870 if(id > -1)
26871 portals.del(id,true);
26872 }
26873 }
26874 break;
26875 }
26876 case PORTALUSESPRITE:
26877 do_portalusesprite();
26878 break;
26879 case SAVEDPORTALREMOVE:
26880 {
26881 if(savedportal* sp = checkSavedPortal(GET_REF(savportalref), true))
26882 {
26883 if(sp == &(game->saved_mirror_portal))
26884 sp->clear();
26885 else
26886 {
26887 //ensure all pointers to the object are cleared before deleting
26888 portals.forEach([&](sprite& spr)
26889 {
26890 portal* tmp = (portal*)&spr;
26891 if(sp->getUID() == tmp->saved_data)
26892 {
26893 tmp->saved_data = 0;
26894 }
26895 return false;
26896 });
26897 //delete the savedportal object from the vector
26898 for(auto it = game->user_portals.begin();
26899 it != game->user_portals.end();)
26900 {
26901 savedportal& tmp = *it;
26902 if(sp == &tmp)
26903 {
26904 game->user_portals.erase(it);
26905 break;
26906 }
26907 else ++it;
26908 }
26909 }
26910 }
26911 break;
26912 }
26913 case SAVEDPORTALGENERATE:
26914 {
26915 auto retval = 0;
26916 if(savedportal* sp = checkSavedPortal(GET_REF(savportalref)))
26917 {
26918 retval = getPortalFromSaved(sp);
26919 if(!retval)
26920 {
26921 if(portal* p = loadportal(*sp))
26922 if(portals.add(p))
26923 retval = p->getUID();
26924 }
26925 }
26926 SET_D(rEXP1, retval);
26927 break;
26928 }
26929
26930 case LINKEXPLODER:
26931 {
26932 int32_t mode = get_register(sarg1) / 10000;
26933 if ( (unsigned) mode > 2 )
26934 {
26935 Z_scripterrlog("Invalid mode (%d) passed to Hero->Explode(int32_t mode)\n",mode);
26936 }
26937 else Hero.explode(mode);
26938 break;
26939 }
26940 case NPCEXPLODER:
26941 {
26942 int32_t mode = get_register(sarg1) / 10000;
26943 if ( (unsigned) mode > 2 )
26944 {
26945 Z_scripterrlog("Invalid mode (%d) passed to npc->Explode(int32_t mode)\n",mode);
26946 }
26947 else
26948 {
26949 if(GuyH::loadNPC(GET_REF(npcref)) == SH::_NoError)
26950 {
26951 GuyH::getNPC()->explode(mode);
26952 }
26953 }
26954 break;
26955 }
26956
26957 case ITEMEXPLODER:
26958 {
26959
26960 int32_t mode = get_register(sarg1) / 10000;
26961 if ( (unsigned) mode > 2 )
26962 {
26963 Z_scripterrlog("Invalid mode (%d) passed to item->Explode(int32_t mode)\n",mode);
26964 }
26965 else
26966 {
26967 if(ItemH::loadItem(GET_REF(itemref)) == SH::_NoError)
26968 {
26969 ItemH::getItem()->explode(mode);
26970 }
26971 }
26972 break;
26973 }
26974 case LWEAPONEXPLODER:
26975 {
26976 int32_t mode = get_register(sarg1) / 10000;
26977 if ( (unsigned) mode > 2 )
26978 {
26979 Z_scripterrlog("Invalid mode (%d) passed to lweapon->Explode(int32_t mode)\n",mode);
26980 }
26981 else
26982 {
26983 if(LwpnH::loadWeapon(GET_REF(lwpnref)) == SH::_NoError)
26984 {
26985 LwpnH::getWeapon()->explode(mode);
26986 }
26987 }
26988 break;
26989 }
26990 case EWEAPONEXPLODER:
26991 {
26992 int32_t mode = get_register(sarg1) / 10000;
26993 if ( (unsigned) mode > 2 )
26994 {
26995 Z_scripterrlog("Invalid mode (%d) passed to eweapon->Explode(int32_t mode)\n",mode);
26996 }
26997 else
26998 {
26999 if(EwpnH::loadWeapon(GET_REF(ewpnref)) == SH::_NoError)
27000 {
27001 EwpnH::getWeapon()->explode(mode);
27002 }
27003 }
27004 break;
27005 }
27006
27007 case BOTTLENAMEGET:
27008 {
27009 int32_t arrayptr = get_register(sarg1);
27010 int32_t id = GET_REF(bottletyperef)-1;
27011 if(unsigned(id) > 63)
27012 {
27013 Z_scripterrlog("Invalid bottledata ID (%d) passed to bottledata->GetName().\n", id);
27014 break;
27015 }
27016
27017 if(ArrayH::setArray(arrayptr, QMisc.bottle_types[id].name) == SH::_Overflow)
27018 Z_scripterrlog("Array supplied to 'bottledata->GetName()' not large enough\n");
27019 break;
27020 }
27021 case BOTTLENAMESET:
27022 {
27023 int32_t arrayptr = get_register(sarg1);
27024 int32_t id = GET_REF(bottletyperef)-1;
27025 if(unsigned(id) > 63)
27026 {
27027 Z_scripterrlog("Invalid bottledata ID (%d) passed to bottledata->SetName().\n", id+1);
27028 break;
27029 }
27030 string name;
27031 ArrayH::getString(arrayptr, name, 31);
27032 strcpy(QMisc.bottle_types[id].name, name.c_str());
27033 break;
27034 }
27035 case BSHOPNAMEGET:
27036 {
27037 int32_t arrayptr = get_register(sarg1);
27038 int32_t id = GET_REF(bottleshopref)-1;
27039 if(unsigned(id) > 255)
27040 {
27041 Z_scripterrlog("Invalid bottleshopdata ID (%d) passed to bottleshopdata->GetName().\n", id+1);
27042 break;
27043 }
27044
27045 if(ArrayH::setArray(arrayptr, QMisc.bottle_shop_types[id].name) == SH::_Overflow)
27046 Z_scripterrlog("Array supplied to 'bottleshopdata->GetName()' not large enough\n");
27047 break;
27048 }
27049 case BSHOPNAMESET:
27050 {
27051 int32_t arrayptr = get_register(sarg1);
27052 int32_t id = GET_REF(bottleshopref);
27053 if(unsigned(id) > 255)
27054 {
27055 Z_scripterrlog("Invalid bottleshopdata ID (%d) passed to bottleshopdata->SetName().\n", id);
27056 break;
27057 }
27058 string name;
27059 ArrayH::getString(arrayptr, name, 31);
27060 strcpy(QMisc.bottle_shop_types[id].name, name.c_str());
27061 break;
27062 }
27063
27064 case RUNITEMSCRIPT:
27065 {
27066 15 int32_t itemid = GET_REF(itemdataref);
27067
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if(unsigned(itemid) > MAXITEMS) break;
27068 15 int32_t mode = get_register(sarg1) / 10000;
27069 15 auto& data = get_script_engine_data(ScriptType::Item, itemid);
27070
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
15 switch(mode)
27071 {
27072 case 0:
27073 {
27074 data.doscript = 4;
27075 break;
27076 }
27077 case 1:
27078 {
27079 if ( itemsbuf[itemid].script != 0 ) //&& !data.doscript )
27080 {
27081 if ( !data.doscript )
27082 {
27083 data.clear_ref();
27084 data.doscript = 1;
27085 //ZScriptVersion::RunScript(ScriptType::Item, itemsbuf[itemid].script, itemid);
27086 }
27087 else
27088 {
27089 //Emily, clear the stack here, clear refinfo, and set up to run again on the next frame from the beginning.
27090 }
27091 }
27092 break;
27093 }
27094 15 case 2:
27095 default:
27096 {
27097
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 if ( itemsbuf[itemid].script != 0 ) //&& !data.doscript )
27098 {
27099
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if (data.doscript != 2 )data.doscript = 2;
27100 15 }
27101 15 break;
27102 }
27103 /*
27104 case 0:
27105 {
27106 data.doscript = 0;
27107 break;
27108 }
27109 default:
27110 {
27111
27112 if ( itemsbuf[itemid].script != 0 ) //&& !data.doscript )
27113 {
27114 //itemScriptData[itemid].Clear();
27115 //for ( int32_t q = 0; q < 1024; q++ ) item_stack[itemid][q] = 0;
27116 //ZScriptVersion::RunScript(ScriptType::Item, itemsbuf[itemid].script, itemid & 0xFFF);
27117 data.doscript = 2;
27118 }
27119 break;
27120 }
27121 */
27122 }
27123 15 break;
27124 }
27125
27126 //Game over Screen
27127 case SETCONTINUESCREEN: FFScript::FFChangeSubscreenText(); break;
27128 case SETCONTINUESTRING: FFScript::FFSetSaveScreenSetting(); break;
27129
27130 case LWPNDEL:
27131 {
27132
3/4
✓ Branch 0 taken 2509 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2509 times.
2511 if(type == ScriptType::Lwpn && ri->lwpnref == i)
27133 {
27134 2509 FFCore.do_lweapon_delete();
27135 2509 return RUNSCRIPT_SELFDELETE;
27136 }
27137
27138 2 FFCore.do_lweapon_delete();
27139 2 break;
27140 }
27141 case EWPNDEL:
27142 {
27143
3/4
✓ Branch 0 taken 1438 times.
✓ Branch 1 taken 44 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1438 times.
1482 if(type == ScriptType::Ewpn && ri->ewpnref == i)
27144 {
27145 1438 FFCore.do_eweapon_delete();
27146 1438 return RUNSCRIPT_SELFDELETE;
27147 }
27148
27149 44 FFCore.do_eweapon_delete();
27150 44 break;
27151 }
27152
27153 case PLAYENHMUSICEX:
27154 // DEPRECATED
27155 do_enh_music(false);
27156 break;
27157
27158 case GETENHMUSICPOS:
27159 FFCore.do_get_music_position();
27160 break;
27161
27162 case SETENHMUSICPOS:
27163 FFCore.do_set_music_position(false);
27164 break;
27165
27166 case SETENHMUSICSPEED:
27167 FFCore.do_set_music_speed(false);
27168 break;
27169
27170 case GETENHMUSICLEN:
27171 FFCore.do_get_music_length();
27172 break;
27173
27174 case SETENHMUSICLOOP:
27175 3 FFCore.do_set_music_loop();
27176 3 break;
27177
27178 case ENHCROSSFADE:
27179 5 do_enh_music_crossfade();
27180 5 break;
27181
27182 case DIREXISTS:
27183 FFCore.do_checkdir(true);
27184 break;
27185
27186 case FILEEXISTS:
27187 FFCore.do_checkdir(false);
27188 break;
27189
27190 case FILESYSREMOVE:
27191 FFCore.do_fs_remove();
27192 break;
27193
27194 case TOBYTE:
27195 do_tobyte();
27196 break;
27197 case TOWORD:
27198 do_toword();
27199 break;
27200 case TOSHORT: do_toshort(); break;
27201 case TOSIGNEDBYTE: do_tosignedbyte(); break;
27202 case TOINTEGER: do_tointeger(); break;
27203 case CEILING: do_ceiling(); break;
27204 case FLOOR: do_floor(); break;
27205 case TRUNCATE: do_trunc(); break;
27206 case ROUND: do_round(); break;
27207 case ROUNDAWAY: do_roundaway(); break;
27208
27209 //Stack
27210 case STACKFREE:
27211 {
27212 if(user_stack* st = checkStack(GET_REF(stackref), true))
27213 {
27214 free_script_object(st->id);
27215 }
27216 break;
27217 }
27218 case STACKOWN:
27219 {
27220 if(user_stack* st = checkStack(GET_REF(stackref)))
27221 {
27222 own_script_object(st, type, i);
27223 }
27224 break;
27225 }
27226 case STACKCLEAR:
27227 {
27228 if(user_stack* st = checkStack(GET_REF(stackref)))
27229 {
27230 st->clearStack();
27231 }
27232 break;
27233 }
27234 case STACKGET:
27235 {
27236 if(user_stack* st = checkStack(GET_REF(stackref), true))
27237 {
27238 int32_t indx = get_register(sarg1); //NOT /10000
27239 set_register(sarg1, st->get(indx)); //NOT *10000
27240 }
27241 else set_register(sarg1, 0L);
27242 break;
27243 }
27244 case STACKSET:
27245 {
27246 if(user_stack* st = checkStack(GET_REF(stackref), true))
27247 {
27248 int32_t indx = get_register(sarg1); //NOT /10000
27249 int32_t val = get_register(sarg2); //NOT /10000
27250 st->set(indx, val); //NOT *10000
27251 }
27252 break;
27253 }
27254 case STACKPOPBACK:
27255 {
27256 if(user_stack* st = checkStack(GET_REF(stackref), true))
27257 {
27258 set_register(sarg1, st->pop_back()); //NOT *10000
27259 }
27260 else set_register(sarg1, 0L);
27261 break;
27262 }
27263 case STACKPOPFRONT:
27264 {
27265 if(user_stack* st = checkStack(GET_REF(stackref), true))
27266 {
27267 set_register(sarg1, st->pop_front()); //NOT *10000
27268 }
27269 else set_register(sarg1, 0L);
27270 break;
27271 }
27272 case STACKPEEKBACK:
27273 {
27274 if(user_stack* st = checkStack(GET_REF(stackref), true))
27275 {
27276 set_register(sarg1, st->peek_back()); //NOT *10000
27277 }
27278 else set_register(sarg1, 0L);
27279 break;
27280 }
27281 case STACKPEEKFRONT:
27282 {
27283 if(user_stack* st = checkStack(GET_REF(stackref), true))
27284 {
27285 set_register(sarg1, st->peek_front()); //NOT *10000
27286 }
27287 else set_register(sarg1, 0L);
27288 break;
27289 }
27290 case STACKPUSHBACK:
27291 {
27292 if(user_stack* st = checkStack(GET_REF(stackref), true))
27293 {
27294 int32_t val = get_register(sarg1); //NOT /10000
27295 st->push_back(val);
27296 }
27297 break;
27298 }
27299 case STACKPUSHFRONT:
27300 {
27301 if(user_stack* st = checkStack(GET_REF(stackref), true))
27302 {
27303 int32_t val = get_register(sarg1); //NOT /10000
27304 st->push_front(val);
27305 }
27306 break;
27307 }
27308
27309 //Module
27310 case MODULEGETIC:
27311 {
27312
27313 int32_t buf_pointer = SH::get_arg(sarg1, false) / 10000;
27314 int32_t element = SH::get_arg(sarg2, false) / 10000;
27315
27316 if ( ((unsigned)element) > 511 )
27317 {
27318 Z_scripterrlog("Illegal itemclass supplied to ZInfo->GetItemClass().\nLegal values are 1 to 511.\n");
27319 }
27320 else
27321 {
27322 char buffer[256] = {0};
27323 strcpy(buffer,ZI.getItemClassName(element));
27324 buffer[255] = '\0';
27325 if(ArrayH::setArray(buf_pointer, buffer) == SH::_Overflow)
27326 {
27327 Z_scripterrlog("Dest string supplied to 'Module->GetItemClass()' is not large enough\n");
27328 }
27329 }
27330
27331 break;
27332 }
27333
27334 //{ Randgen Stuff
27335 case RNGRAND1:
27336 if(user_rng* r = checkRNG(GET_REF(rngref)))
27337 {
27338 SET_D(rEXP1, r->rand(214748, -214748)*10000L);
27339 }
27340 else SET_D(rEXP1, -10000L);
27341 break;
27342 case RNGRAND2:
27343
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58074 times.
58074 if(user_rng* r = checkRNG(GET_REF(rngref)))
27344 {
27345 58074 set_register(sarg1,r->rand(get_register(sarg1)/10000L)*10000L);
27346 58074 }
27347 else set_register(sarg1,-10000L);
27348 58074 break;
27349 case RNGRAND3:
27350
1/2
✓ Branch 0 taken 463835 times.
✗ Branch 1 not taken.
463835 if(user_rng* r = checkRNG(GET_REF(rngref)))
27351 {
27352 463835 set_register(sarg1,r->rand(get_register(sarg1)/10000L, get_register(sarg2)/10000L)* 10000L);
27353 463835 }
27354 else set_register(sarg1,-10000L);
27355 463835 break;
27356 case RNGLRAND1:
27357 if(user_rng* r = checkRNG(GET_REF(rngref)))
27358 {
27359 SET_D(rEXP1, r->rand());
27360 }
27361 else SET_D(rEXP1, -10000L);
27362 break;
27363 case RNGLRAND2:
27364 if(user_rng* r = checkRNG(GET_REF(rngref)))
27365 {
27366 SET_D(rEXP1, r->rand(get_register(sarg1)));
27367 }
27368 else SET_D(rEXP1, -10000L);
27369 break;
27370 case RNGLRAND3:
27371 if(user_rng* r = checkRNG(GET_REF(rngref)))
27372 {
27373 SET_D(rEXP1, r->rand(get_register(sarg1), get_register(sarg2)));
27374 }
27375 else SET_D(rEXP1, -10000L);
27376 break;
27377 case RNGSEED:
27378
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
73 if(user_rng* r = checkRNG(GET_REF(rngref)))
27379 {
27380 73 r->srand(get_register(sarg1));
27381 73 }
27382 73 break;
27383 case RNGRSEED:
27384 if(user_rng* r = checkRNG(GET_REF(rngref)))
27385 {
27386 SET_D(rEXP1, r->srand());
27387 }
27388 else SET_D(rEXP1, -10000);
27389 break;
27390 case RNGFREE:
27391
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(user_rng* r = checkRNG(GET_REF(rngref), true))
27392 {
27393 6 free_script_object(r->id);
27394 6 }
27395 6 break;
27396 case RNGOWN:
27397
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if(user_rng* r = checkRNG(GET_REF(rngref), false))
27398 {
27399 8 own_script_object(r, type, i);
27400 8 }
27401 8 break;
27402 //}
27403 case LOADSAVEMENU:
27404 {
27405 auto val = get_register(sarg1)/10000;
27406 if (unsigned(val-1) >= NUM_SAVE_MENUS)
27407 {
27408 Z_scripterrlog("Tried to load invalid save_menu index '%d'\n", val);
27409 }
27410 ri->savemenuref = SET_D(rEXP1, val);
27411 break;
27412 }
27413 case LOADGENERICDATA:
27414 137140 FFCore.do_loadgenericdata(false); break;
27415 case RUNGENFRZSCR:
27416 {
27417 10 bool r = FFCore.runGenericFrozenEngine(word(GET_REF(genericdataref)));
27418 10 set_register(sarg1, r ? 10000L : 0L);
27419 10 break;
27420 }
27421
27422 ///----------------------------------------------------------------------------------------------------//
27423
27424 case SUBDATA_GET_NAME:
27425 {
27426 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref)))
27427 {
27428 auto aptr = get_register(sarg1);
27429 if(ArrayH::setArray(aptr, sub->name, true) == SH::_Overflow)
27430 Z_scripterrlog("Array supplied to 'subscreendata->GetName()' not large enough,"
27431 " and couldn't be resized!\n");
27432 }
27433 break;
27434 }
27435 case SUBDATA_SET_NAME:
27436 {
27437 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref)))
27438 {
27439 auto aptr = get_register(sarg1);
27440 ArrayH::getString(aptr, sub->name);
27441 }
27442 break;
27443 }
27444 case SUBDATA_SWAP_PAGES:
27445 {
27446 ri->subscreendataref = SH::read_stack(ri->sp+2);
27447 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref)))
27448 {
27449 int p1 = SH::read_stack(ri->sp+1) / 10000;
27450 int p2 = SH::read_stack(ri->sp+0) / 10000;
27451 if(unsigned(p1) >= sub->pages.size())
27452 Z_scripterrlog("Invalid page index '%d' passed to subscreendata->SwapPages()\n", p1);
27453 else if(unsigned(p2) >= sub->pages.size())
27454 Z_scripterrlog("Invalid page index '%d' passed to subscreendata->SwapPages()\n", p2);
27455 else sub->swap_pages(p1,p2);
27456 }
27457 break;
27458 }
27459 case SUBPAGE_SWAP_WIDG:
27460 {
27461 ri->subscreenpageref = SH::read_stack(ri->sp+2);
27462 if(SubscrPage* pg = checkSubPage(GET_REF(subscreenpageref)))
27463 {
27464 int p1 = SH::read_stack(ri->sp+1) / 10000;
27465 int p2 = SH::read_stack(ri->sp+0) / 10000;
27466 if(unsigned(p1) >= pg->size())
27467 Z_scripterrlog("Invalid page index '%d' passed to subscreenpage->SwapWidgets()\n", p1);
27468 else if(unsigned(p2) >= pg->size())
27469 Z_scripterrlog("Invalid page index '%d' passed to subscreenpage->SwapWidgets()\n", p2);
27470 else pg->swap_widg(p1,p2);
27471 }
27472 break;
27473 }
27474 case SUBPAGE_FIND_WIDGET:
27475 {
27476 14870 SET_D(rEXP1, 0);
27477
27478 14870 ri->subscreenpageref = SH::read_stack(ri->sp+1);
27479
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 14870 times.
✓ Branch 2 taken 14870 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 14870 times.
14870 if(SubscrPage* pg = checkSubPage(GET_REF(subscreenpageref), {sstACTIVE, sstMAP}))
27480 {
27481 14870 int cursorpos = SH::read_stack(ri->sp+0) / 10000;
27482
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14870 times.
14870 if(auto* widg = pg->get_widg_pos(cursorpos,false))
27483 {
27484 14870 auto q = pg->widget_index(widg);
27485
1/2
✓ Branch 0 taken 14870 times.
✗ Branch 1 not taken.
14870 if(q > -1)
27486 {
27487 44610 auto [sub,ty,pgid,_ind] = from_subref(GET_REF(subscreenpageref));
27488 44610 SET_D(rEXP1, get_subref(sub,ty,pgid,q));
27489 14870 }
27490 14870 }
27491 14870 }
27492 14870 break;
27493 }
27494 case SUBPAGE_FIND_WIDGET_BY_LABEL:
27495 {
27496 17877 SET_D(rEXP1, 0);
27497
27498 17877 ri->subscreenpageref = SH::read_stack(ri->sp+1);
27499
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17877 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17877 times.
17877 if(SubscrPage* pg = checkSubPage(GET_REF(subscreenpageref)))
27500 {
27501 17877 int aptr = SH::read_stack(ri->sp+0);
27502 17877 std::string lbl;
27503
1/2
✓ Branch 0 taken 17877 times.
✗ Branch 1 not taken.
17877 ArrayH::getString(aptr, lbl);
27504
1/2
✓ Branch 0 taken 17877 times.
✗ Branch 1 not taken.
17877 if(lbl.size())
27505 {
27506
1/2
✓ Branch 0 taken 17877 times.
✗ Branch 1 not taken.
17877 auto q = pg->find_label_index(lbl);
27507
2/2
✓ Branch 0 taken 5703 times.
✓ Branch 1 taken 12174 times.
17877 if(q > -1)
27508 {
27509 36522 auto [sub,ty,pgid,_ind] = from_subref(GET_REF(subscreenpageref));
27510 36522 SET_D(rEXP1, get_subref(sub,ty,pgid,q));
27511 12174 }
27512 17877 }
27513 17877 }
27514 17877 break;
27515 }
27516 case SUBPAGE_MOVE_SEL:
27517 {
27518 #define SUBSEL_FLAG_NO_NONEQUIP 0x01
27519 #define SUBSEL_FLAG_NEED_ITEM 0x02
27520
27521 SET_D(rEXP1, 0);
27522
27523 ri->subscreenpageref = SH::read_stack(ri->sp+3);
27524 if(SubscrPage* pg = checkSubPage(GET_REF(subscreenpageref)))
27525 {
27526 int flags = SH::read_stack(ri->sp+0) / 10000;
27527 int dir = SH::read_stack(ri->sp+1) / 10000;
27528 int pos = SH::read_stack(ri->sp+2) / 10000;
27529 switch(dir)
27530 {
27531 case up:
27532 dir = SEL_UP;
27533 break;
27534 case down:
27535 dir = SEL_DOWN;
27536 break;
27537 case left:
27538 dir = SEL_LEFT;
27539 break;
27540 case right: default:
27541 dir = SEL_RIGHT;
27542 break;
27543 }
27544
27545 auto newpos = pg->movepos_legacy(dir, (pos<<8)|pg->getIndex(),
27546 255, 255, 255, flags&SUBSEL_FLAG_NO_NONEQUIP,
27547 flags&SUBSEL_FLAG_NEED_ITEM, true) >> 8;
27548 SET_D(rEXP1, 10000*newpos);
27549 }
27550 break;
27551 }
27552 case SUBPAGE_NEW_WIDG:
27553 {
27554 SET_D(rEXP1, 0);
27555
27556 ri->subscreenpageref = SH::read_stack(ri->sp+1);
27557 if(SubscrPage* pg = checkSubPage(GET_REF(subscreenpageref)))
27558 {
27559 if(pg->size() == 0x2000)
27560 break; //Page is full!
27561 int ty = SH::read_stack(ri->sp+0) / 10000;
27562 if(auto* widg = SubscrWidget::newType(ty))
27563 {
27564 widg->posflags = sspUP | sspDOWN | sspSCROLLING;
27565 widg->w = 1;
27566 widg->h = 1;
27567 pg->push_back(widg);
27568 auto [sub,ty,pgid,_ind] = from_subref(GET_REF(subscreenpageref));
27569 SET_D(rEXP1, get_subref(sub,ty,pgid,pg->size()-1));
27570 }
27571 else Z_scripterrlog("Invalid type %d passed to subscreenpage->CreateWidget()\n",ty);
27572 }
27573 break;
27574 }
27575 case SUBPAGE_DELETE:
27576 {
27577 if(SubscrPage* pg = checkSubPage(GET_REF(subscreenpageref)))
27578 {
27579 auto [sub,_ty] = load_subdata(GET_REF(subscreenpageref));
27580 sub->delete_page(pg->getIndex());
27581 }
27582 break;
27583 }
27584 case SUBWIDG_GET_SELTEXT_OVERRIDE:
27585 {
27586 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
27587 {
27588 auto aptr = get_register(sarg1);
27589 if(ArrayH::setArray(aptr, widg->override_text, true) == SH::_Overflow)
27590 Z_scripterrlog("Array supplied to 'subscreenwidget->GetSelTextOverride()' not large enough,"
27591 " and couldn't be resized!\n");
27592 }
27593 break;
27594 }
27595 case SUBWIDG_SET_SELTEXT_OVERRIDE:
27596 {
27597 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
27598 {
27599 auto aptr = get_register(sarg1);
27600 ArrayH::getString(aptr, widg->override_text);
27601 }
27602 break;
27603 }
27604 case SUBWIDG_GET_LABEL:
27605 {
27606
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 828 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 828 times.
828 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
27607 {
27608 828 auto aptr = get_register(sarg1);
27609
1/2
✓ Branch 0 taken 828 times.
✗ Branch 1 not taken.
828 if(ArrayH::setArray(aptr, widg->label, true) == SH::_Overflow)
27610 Z_scripterrlog("Array supplied to 'subscreenwidget->GetLabel()' not large enough,"
27611 " and couldn't be resized!\n");
27612 828 }
27613 828 break;
27614 }
27615 case SUBWIDG_SET_LABEL:
27616 {
27617 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
27618 {
27619 auto aptr = get_register(sarg1);
27620 ArrayH::getString(aptr, widg->label);
27621 }
27622 break;
27623 }
27624 case SUBWIDG_CHECK_CONDITIONS:
27625 {
27626 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
27627 {
27628 set_register(sarg1, widg->check_conditions() ? 10000 : 0);
27629 }
27630 break;
27631 }
27632 case SUBWIDG_CHECK_VISIBLE:
27633 {
27634 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
27635 {
27636 extern int current_subscr_pos;
27637 set_register(sarg1, widg->visible(current_subscr_pos, game->should_show_time()) ? 10000 : 0);
27638 }
27639 break;
27640 }
27641 case SUBWIDG_TY_GETTEXT:
27642 {
27643 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
27644 {
27645 optional<string> str;
27646 byte ty = widg->getType();
27647 switch(ty)
27648 {
27649 case widgTEXT:
27650 str = ((SW_Text*)widg)->text;
27651 break;
27652 case widgTEXTBOX:
27653 str = ((SW_TextBox*)widg)->text;
27654 break;
27655 case widgITMCOOLDOWNTEXT:
27656 str = ((SW_ItemCooldownText*)widg)->get_text();
27657 break;
27658 default:
27659 bad_subwidg_type(true, ty);
27660 break;
27661 }
27662 if(str)
27663 {
27664 auto aptr = get_register(sarg1);
27665 if(ArrayH::setArray(aptr, *str, true) == SH::_Overflow)
27666 Z_scripterrlog("Array supplied to 'subscreenwidget->GetText()' not large enough,"
27667 " and couldn't be resized!\n");
27668 }
27669 }
27670 break;
27671 }
27672 case SUBWIDG_TY_SETTEXT:
27673 {
27674
2/4
✓ Branch 0 taken 76234 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 76234 times.
76234 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
27675 {
27676 76234 std::string* str = nullptr;
27677 76234 byte ty = widg->getType();
27678
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 68852 times.
✓ Branch 2 taken 7382 times.
76234 switch(ty)
27679 {
27680 case widgTEXT:
27681 68852 str = &((SW_Text*)widg)->text;
27682 68852 break;
27683 case widgTEXTBOX:
27684 7382 str = &((SW_TextBox*)widg)->text;
27685 7382 break;
27686 default:
27687 bad_subwidg_type(true, ty);
27688 break;
27689 }
27690
1/2
✓ Branch 0 taken 76234 times.
✗ Branch 1 not taken.
76234 if(str)
27691 {
27692 76234 auto aptr = get_register(sarg1);
27693 76234 ArrayH::getString(aptr, *str);
27694 76234 }
27695 76234 }
27696 76234 break;
27697 }
27698
27699 case COMBOD_GET_TRIGGER:
27700 {
27701 if(checkComboRef())
27702 {
27703 auto aptr = get_register(sarg1) / 10000;
27704 string name;
27705 ArrayH::getString(aptr, name, 256);
27706 newcombo const& cmb = combobuf[GET_REF(combodataref)];
27707 int32_t ret = 0;
27708 for(size_t idx = 0; idx < cmb.triggers.size(); ++idx)
27709 {
27710 if(cmb.triggers[idx].label == name)
27711 {
27712 ret = dword(GET_REF(combodataref)) | (dword(idx)<<24);
27713 break;
27714 }
27715 }
27716
27717 set_register(sarg1, ret);
27718 }
27719 break;
27720 }
27721 case CMBTRIG_GET_LABEL:
27722 {
27723 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
27724 {
27725 auto aptr = get_register(sarg1) / 10000;
27726 if(ArrayH::setArray(aptr, trig->label, true) == SH::_Overflow)
27727 Z_scripterrlog("Array supplied to 'combotrigger->GetLabel()' not large enough,"
27728 " and couldn't be resized!\n");
27729 }
27730 break;
27731 }
27732 case CMBTRIG_SET_LABEL:
27733 {
27734 if (auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
27735 {
27736 auto aptr = get_register(sarg1) / 10000;
27737 ArrayH::getString(aptr, trig->label);
27738 }
27739 break;
27740 }
27741
27742 case REF_INC:
27743 {
27744
2/2
✓ Branch 0 taken 1578226 times.
✓ Branch 1 taken 796 times.
1579022 if (sarg1 == -1)
27745 {
27746 796 script_object_ref_inc(ri->thiskey);
27747 796 break;
27748 }
27749
27750 1578226 int offset = GET_D(rSFRAME) + sarg1;
27751
1/2
✓ Branch 0 taken 1578226 times.
✗ Branch 1 not taken.
1578226 if (!ri->stackPosHasObject(offset))
27752 {
27753 assert(false);
27754 break;
27755 }
27756
27757 1578226 uint32_t id = SH::read_stack(offset);
27758 1578226 script_object_ref_inc(id);
27759 1578226 break;
27760 }
27761 case REF_DEC:
27762 {
27763
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 796 times.
796 if (sarg1 == -1)
27764 {
27765 796 script_object_ref_dec(ri->thiskey);
27766 796 break;
27767 }
27768
27769 int offset = GET_D(rSFRAME) + sarg1;
27770 if (!ri->stackPosHasObject(offset))
27771 {
27772 assert(false);
27773 break;
27774 }
27775
27776 uint32_t id = SH::read_stack(offset);
27777 script_object_ref_dec(id);
27778 break;
27779 }
27780 case REF_AUTORELEASE:
27781 {
27782 3237854 uint32_t id = get_register(sarg1);
27783
4/4
✓ Branch 0 taken 2211867 times.
✓ Branch 1 taken 1025987 times.
✓ Branch 2 taken 15559 times.
✓ Branch 3 taken 2196308 times.
3237854 if (id && !util::contains(script_object_autorelease_pool, id))
27784 {
27785 2196308 script_object_autorelease_pool.push_back(id);
27786
2/2
✓ Branch 0 taken 17924 times.
✓ Branch 1 taken 2178384 times.
2196308 if (auto object = get_script_object_checked(id))
27787 2178384 object->ref_count++;
27788 2196308 }
27789 3237854 break;
27790 }
27791 case REF_COUNT:
27792 {
27793
1/2
✓ Branch 0 taken 1428 times.
✗ Branch 1 not taken.
1428 if (!use_testingst_start)
27794 {
27795 scripting_log_error_with_context("This function can only be used in test mode");
27796 break;
27797 }
27798
27799 1428 uint32_t id = get_register(sarg1);
27800 1428 auto object = get_script_object(id);
27801
2/2
✓ Branch 0 taken 1405 times.
✓ Branch 1 taken 23 times.
1428 int count = object ? object->ref_count : -1;
27802 1428 set_register(sarg1, count);
27803 1428 break;
27804 }
27805 case MARK_TYPE_STACK:
27806 {
27807 1578226 int offset = GET_D(rSFRAME) + sarg2;
27808
1/2
✓ Branch 0 taken 1578226 times.
✗ Branch 1 not taken.
1578226 if (offset < 0 || offset >= MAX_STACK_SIZE)
27809 {
27810 assert(false);
27811 break;
27812 }
27813
27814
1/2
✓ Branch 0 taken 1578226 times.
✗ Branch 1 not taken.
1578226 if (sarg1)
27815 1578226 ri->stack_pos_is_object.insert(offset);
27816 else
27817 ri->stack_pos_is_object.erase(offset);
27818 1578226 break;
27819 }
27820 case MARK_TYPE_REG:
27821 {
27822 3218 markRegisterType(sarg1, sarg2);
27823 3218 break;
27824 }
27825 case REF_REMOVE:
27826 {
27827 int offset = GET_D(rSFRAME) + sarg1;
27828 script_remove_object_ref(offset);
27829 break;
27830 }
27831 case GC:
27832 {
27833
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 240 times.
240 if (!use_testingst_start)
27834 {
27835 Z_error_fatal("GC can only be used in test mode\n");
27836 break;
27837 }
27838
27839 240 run_gc();
27840 240 break;
27841 }
27842 case SET_OBJECT:
27843 {
27844 2654 int value = get_register(sarg2);
27845
3/4
✓ Branch 0 taken 2654 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 31 times.
✓ Branch 3 taken 2623 times.
2654 if (sarg1 >= GD(0) && sarg1 <= GD(MAX_SCRIPT_REGISTERS))
27846 {
27847 2623 int index = sarg1-GD(0);
27848
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2623 times.
2623 assert(game->global_d_types[index] != script_object_type::none);
27849 2623 script_object_ref_inc(value);
27850 2623 script_object_ref_dec(game->global_d[index]);
27851 2623 game->global_d[index] = value;
27852 2623 }
27853
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 else if (zasm_array_supports(sarg1))
27854 {
27855 31 auto type = (script_object_type)sarg3;
27856
27857 31 int zasm_var = sarg1;
27858 31 int index = GET_D(rINDEX) / 10000;
27859 31 int ref_arg = get_register_ref_dependency(zasm_var).value_or(0);
27860
1/2
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
31 int ref = ref_arg ? get_ref(ref_arg) : 0;
27861 31 zasm_array_set(zasm_var, ref, index, value, type);
27862 31 }
27863 else NOTREACHED();
27864 2654 break;
27865 }
27866 case LOAD_INTERNAL_ARRAY:
27867 {
27868 4 do_load_internal_array();
27869 4 break;
27870 }
27871 case LOAD_INTERNAL_ARRAY_REF:
27872 {
27873 26 do_load_internal_array_ref();
27874 26 break;
27875 }
27876
27877 default:
27878 {
27879
1/2
✓ Branch 0 taken 6689298 times.
✗ Branch 1 not taken.
6689298 if (auto r = scripting_engine_run_command(scommand))
27880 {
27881
2/2
✓ Branch 0 taken 6689292 times.
✓ Branch 1 taken 6 times.
6689298 if (*r != RUNSCRIPT_OK)
27882 6 return *r;
27883 6689292 break;
27884 }
27885
27886 scripting_log_error_with_context("Invalid ZASM command {} reached; terminating", scommand);
27887 hit_invalid_zasm = true;
27888 scommand = 0xFFFF;
27889 #ifdef _DEBUG
27890 Z_error_fatal("Invalid ZASM command: %d\n", scommand);
27891 #endif
27892 break;
27893 }
27894 }
27895
1/2
✓ Branch 0 taken 1530152249 times.
✗ Branch 1 not taken.
1530152249 if(earlyretval == RUNSCRIPT_SELFDELETE)
27896 {
27897 earlyretval = -1;
27898 return RUNSCRIPT_SELFDELETE;
27899 }
27900
1/2
✓ Branch 0 taken 1530152249 times.
✗ Branch 1 not taken.
1530152249 if (ri->overflow)
27901 {
27902 if (old_script_funcrun)
27903 return RUNSCRIPT_OK;
27904 scommand = 0xFFFF;
27905 }
27906
1/2
✓ Branch 0 taken 1530152249 times.
✗ Branch 1 not taken.
1530152249 if(hit_invalid_zasm) break;
27907
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 1530152249 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1530152249 if(old_script_funcrun && (ri->pc == MAX_PC || scommand == RETURN))
27908 return RUNSCRIPT_OK;
27909
27910
2/2
✓ Branch 0 taken 1526428671 times.
✓ Branch 1 taken 3723578 times.
1530152249 if (type == ScriptType::Combo)
27911 {
27912
1/2
✓ Branch 0 taken 3723578 times.
✗ Branch 1 not taken.
3723578 if(combopos_modified == i)
27913 {
27914 //Combo changed! Abort script!
27915 return RUNSCRIPT_OK;
27916 }
27917 3723578 }
27918
2/2
✓ Branch 0 taken 93174 times.
✓ Branch 1 taken 1530059075 times.
1530152249 if(scommand != 0xFFFF)
27919 {
27920
2/2
✓ Branch 0 taken 1520287561 times.
✓ Branch 1 taken 9771514 times.
1530059075 if(increment) ri->pc++;
27921 9771514 else increment = true;
27922
1/2
✓ Branch 0 taken 1530059075 times.
✗ Branch 1 not taken.
1530059075 if ( ri->pc == MAX_PC ) //rolled over from overflow?
27923 {
27924 Z_scripterrlog("Script PC overflow! Too many ZASM lines?\n");
27925 ri->pc = curscript->pc;
27926 scommand = 0xFFFF;
27927 }
27928 1530059075 }
27929
27930
1/2
✓ Branch 0 taken 1530152249 times.
✗ Branch 1 not taken.
1530152249 if(earlyretval > -1) //Should this be below the 'commands_run += 1'? Unsure. -Em
27931 {
27932 auto v = earlyretval;
27933 earlyretval = -1;
27934 return earlyretval;
27935 }
27936
27937 // If running a JIT compiled script, we're only here to do a few commands.
27938 1530152249 commands_run += 1;
27939
4/4
✓ Branch 0 taken 1493936174 times.
✓ Branch 1 taken 36216075 times.
✓ Branch 2 taken 157731921 times.
✓ Branch 3 taken 1336204253 times.
1530152249 if (is_jitted && commands_run == j_instance->uncompiled_command_count)
27940 {
27941 1336204253 current_zasm_command=(ASM_DEFINE)0;
27942 1336204253 break;
27943 }
27944 }
27945
2/2
✓ Branch 0 taken 824 times.
✓ Branch 1 taken 1370761602 times.
1370762426 if(script_funcrun) return RUNSCRIPT_OK;
27946
27947
2/2
✓ Branch 0 taken 1370761572 times.
✓ Branch 1 taken 30 times.
1370761602 if(!scriptCanSave)
27948 30 scriptCanSave=true;
27949
27950
2/2
✓ Branch 0 taken 1364107710 times.
✓ Branch 1 taken 6653892 times.
1370761602 if(scommand == WAITDRAW)
27951 {
27952
2/5
✗ Branch 0 not taken.
✓ Branch 1 taken 6637610 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 16282 times.
6653892 switch(type)
27953 {
27954 case ScriptType::Global:
27955 case ScriptType::Hero:
27956 case ScriptType::DMap:
27957 case ScriptType::OnMap:
27958 case ScriptType::ScriptedPassiveSubscreen:
27959 case ScriptType::ScriptedActiveSubscreen:
27960 case ScriptType::Screen:
27961 case ScriptType::Combo:
27962 case ScriptType::NPC:
27963 case ScriptType::Lwpn:
27964 case ScriptType::Ewpn:
27965 case ScriptType::ItemSprite:
27966 6637610 FFCore.waitdraw(type, i) = true;
27967 6637610 break;
27968
27969 case ScriptType::Item:
27970 {
27971 if (!get_qr(qr_NOITEMWAITDRAW))
27972 {
27973 FFCore.waitdraw(ScriptType::Item, i) = true;
27974 }
27975 break;
27976 }
27977
27978 case ScriptType::FFC:
27979 {
27980
2/2
✓ Branch 0 taken 1221 times.
✓ Branch 1 taken 15061 times.
16282 if ( !(get_qr(qr_NOFFCWAITDRAW)) )
27981 {
27982 15061 FFCore.waitdraw(ScriptType::FFC, i) = true;
27983 15061 }
27984 else
27985 {
27986 1221 Z_scripterrlog("Waitdraw cannot be used in script type: %s\n", "ffc, with Script Rule 'No FFC Waitdraw() enabled!");
27987 }
27988 16282 break;
27989 }
27990
27991 case ScriptType::Generic:
27992 case ScriptType::GenericFrozen:
27993 case ScriptType::EngineSubscreen:
27994 //No Waitdraw
27995 break;
27996
27997 default:
27998 Z_scripterrlog("Waitdraw cannot be used in script type: %s\n", ScriptTypeToString(type));
27999 break;
28000 }
28001 6653892 }
28002
28003
2/2
✓ Branch 0 taken 92350 times.
✓ Branch 1 taken 1370669252 times.
1370761602 if(scommand == 0xFFFF) //Quit/command list end reached/bad command
28004 {
28005 92350 script_exit_cleanup(no_dealloc);
28006 92350 return RUNSCRIPT_STOPPED;
28007 }
28008
28009
4/4
✓ Branch 0 taken 1370668034 times.
✓ Branch 1 taken 1218 times.
✓ Branch 2 taken 34555492 times.
✓ Branch 3 taken 1336112542 times.
1370669252 if (is_jitted && commands_run == j_instance->uncompiled_command_count)
28010 1336112542 return RUNSCRIPT_OK;
28011
28012 34556710 ri->pc++;
28013
28014 34556710 return RUNSCRIPT_OK;
28015 1370766379 }
28016
28017 6424 script_data* load_scrdata(ScriptType type, word script, int32_t i)
28018 {
28019
2/15
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 4776 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 1648 times.
✗ Branch 14 not taken.
6424 switch(type)
28020 {
28021 case ScriptType::FFC:
28022 return ffscripts[script];
28023 case ScriptType::NPC:
28024 return guyscripts[guys.getByUID(i)->script];
28025 case ScriptType::Lwpn:
28026 return lwpnscripts[Lwpns.getByUID(i)->script];
28027 case ScriptType::Ewpn:
28028 return ewpnscripts[Ewpns.getByUID(i)->script];
28029 case ScriptType::ItemSprite:
28030 return itemspritescripts[items.getByUID(i)->script];
28031 case ScriptType::Item:
28032 return itemscripts[script];
28033 case ScriptType::Global:
28034 return globalscripts[script];
28035 case ScriptType::Generic:
28036 case ScriptType::GenericFrozen:
28037 1648 return genericscripts[script];
28038 case ScriptType::Hero:
28039 return playerscripts[script];
28040 case ScriptType::DMap:
28041 return dmapscripts[script];
28042 case ScriptType::OnMap:
28043 case ScriptType::ScriptedActiveSubscreen:
28044 case ScriptType::ScriptedPassiveSubscreen:
28045 return dmapscripts[script];
28046 case ScriptType::Screen:
28047 return screenscripts[script];
28048 case ScriptType::Combo:
28049 return comboscripts[script];
28050 case ScriptType::EngineSubscreen:
28051 return subscreenscripts[script];
28052 }
28053 4776 return nullptr;
28054 6424 }
28055
28056 //This keeps ffc scripts running beyond the first frame.
28057 14966613 int32_t ffscript_engine(const bool preload)
28058 {
28059
2/2
✓ Branch 0 taken 14930111 times.
✓ Branch 1 taken 36502 times.
14966613 if(preload)
28060 {
28061 36502 throwGenScriptEvent(GENSCR_EVENT_FFC_PRELOAD);
28062 36502 handle_region_load_trigger();
28063 36502 }
28064
28065
6/6
✓ Branch 0 taken 14964027 times.
✓ Branch 1 taken 2586 times.
✓ Branch 2 taken 2364922 times.
✓ Branch 3 taken 12599105 times.
✓ Branch 4 taken 2350845 times.
✓ Branch 5 taken 14077 times.
14966613 if (!FFCore.system_suspend[susptSCREENSCRIPTS] && FFCore.getQuestHeaderInfo(vZelda) >= 0x255 && !get_qr(qr_ZS_OLD_SUSPEND_FFC))
28066 {
28067 28154 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
28068
4/4
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 14058 times.
✓ Branch 2 taken 19 times.
✓ Branch 3 taken 14039 times.
14077 if ((preload && scr->preloadscript) || !preload)
28069 {
28070
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 14058 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14058 if (scr->script > 0 && FFCore.doscript(ScriptType::Screen, scr->screen))
28071 {
28072 ZScriptVersion::RunScript(ScriptType::Screen, scr->script, scr->screen);
28073 }
28074 14058 }
28075 14077 });
28076 14077 }
28077
28078
2/2
✓ Branch 0 taken 2586 times.
✓ Branch 1 taken 14964027 times.
14966613 if (!FFCore.system_suspend[susptFFCSCRIPTS])
28079 {
28080 //intentional it's for compatability
28081
4/4
✓ Branch 0 taken 2364922 times.
✓ Branch 1 taken 12599105 times.
✓ Branch 2 taken 14077 times.
✓ Branch 3 taken 2350845 times.
14964027 if (FFCore.getQuestHeaderInfo(vZelda) >= 0x255 && get_qr(qr_ZS_OLD_SUSPEND_FFC))
28082 {
28083 5090766 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
28084
4/4
✓ Branch 0 taken 6828 times.
✓ Branch 1 taken 2733093 times.
✓ Branch 2 taken 6749 times.
✓ Branch 3 taken 2726344 times.
2739921 if ((preload && scr->preloadscript) || !preload)
28085 {
28086
3/4
✓ Branch 0 taken 50461 times.
✓ Branch 1 taken 2682711 times.
✓ Branch 2 taken 50461 times.
✗ Branch 3 not taken.
2733172 if (scr->script > 0 && FFCore.doscript(ScriptType::Screen, scr->screen))
28087 {
28088 50461 ZScriptVersion::RunScript(ScriptType::Screen, scr->script, scr->screen);
28089 50461 }
28090 2733172 }
28091 2739921 });
28092 2350845 }
28093
28094 459439502 for_every_ffc([&](const ffc_handle_t& ffc_handle) {
28095
2/2
✓ Branch 0 taken 11826077 times.
✓ Branch 1 taken 432649398 times.
444475475 if(ffc_handle.ffc->script == 0)
28096 432649398 return;
28097
28098
4/4
✓ Branch 0 taken 14710 times.
✓ Branch 1 taken 11811367 times.
✓ Branch 2 taken 11170 times.
✓ Branch 3 taken 3540 times.
11826077 if(preload && !(ffc_handle.ffc->flags&ffc_preload))
28099 11170 return;
28100
28101
4/4
✓ Branch 0 taken 11810348 times.
✓ Branch 1 taken 4559 times.
✓ Branch 2 taken 11715274 times.
✓ Branch 3 taken 95074 times.
11814907 if((ffc_handle.ffc->flags&ffc_ignoreholdup)==0 && Hero.getHoldClk()>0)
28102 95074 return;
28103
28104 11719833 ZScriptVersion::RunScript(ScriptType::FFC, ffc_handle.ffc->script, ffc_handle.id);
28105 444475475 });
28106 14964027 }
28107
28108
28109 14966613 return 0;
28110 }
28111
28112
28113
28114 ///----------------------------------------------------------------------------------------------------
28115
28116 440 void FFScript::user_files_init()
28117 {
28118 440 files_init();
28119 440 }
28120
28121 440 void FFScript::user_dirs_init()
28122 {
28123 440 dirs_init();
28124 440 }
28125 440 void FFScript::user_objects_init()
28126 {
28127 440 ::user_object_init();
28128 440 }
28129
28130 440 void FFScript::user_stacks_init()
28131 {
28132 440 user_stacks.clear();
28133 440 }
28134
28135 1154 void FFScript::user_rng_init()
28136 {
28137 1154 user_rngs.clear();
28138
2/2
✓ Branch 0 taken 295424 times.
✓ Branch 1 taken 1154 times.
296578 for(int32_t q = 0; q < MAX_USER_RNGS; ++q)
28139 {
28140 295424 replay_register_rng(&script_rnggens[q]);
28141
28142 // Just to seed it.
28143 295424 user_rng rng;
28144 295424 rng.set_gen(&script_rnggens[q]);
28145 295424 }
28146 1154 }
28147
28148 440 void FFScript::user_paldata_init()
28149 {
28150 440 user_paldatas.clear();
28151 440 }
28152
28153 440 void FFScript::user_websockets_init()
28154 {
28155 440 websocket_init();
28156 440 }
28157
28158 646 void FFScript::script_arrays_init()
28159 {
28160 646 script_arrays.clear();
28161 646 }
28162
28163 ///----------------------------------------------------------------------------------------------------
28164
28165 8420 void FFScript::do_isvalidbitmap()
28166 {
28167 8420 int32_t id = get_register(sarg1);
28168
28169
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8420 times.
8420 if (id >= 0)
28170 {
28171 8420 auto bmp = user_bitmaps.check(id, true);
28172
3/4
✓ Branch 0 taken 8370 times.
✓ Branch 1 taken 50 times.
✓ Branch 2 taken 8370 times.
✗ Branch 3 not taken.
8420 if (bmp && bmp->u_bmp)
28173 {
28174 8370 set_register(sarg1, 10000);
28175 8370 return;
28176 }
28177 50 }
28178
28179 50 set_register(sarg1, 0);
28180 8420 }
28181 117 void FFScript::do_isallocatedbitmap()
28182 {
28183 117 int32_t id = get_register(sarg1);
28184
28185
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 117 times.
117 if (id >= 0)
28186 {
28187 117 auto bmp = user_bitmaps.check(id, true);
28188
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 115 times.
117 if (bmp)
28189 {
28190 115 set_register(sarg1, 10000);
28191 115 return;
28192 }
28193 2 }
28194
28195 2 set_register(sarg1, 0);
28196 117 }
28197
28198 440 void FFScript::user_bitmaps_init()
28199 {
28200 440 user_bitmaps.clear();
28201 440 }
28202
28203 1509497 int32_t FFScript::do_create_bitmap()
28204 {
28205 1509497 int32_t w = (GET_D(rINDEX2) / 10000);
28206 1509497 int32_t h = (GET_D(rINDEX)/10000);
28207
1/2
✓ Branch 0 taken 1509497 times.
✗ Branch 1 not taken.
1509497 if ( get_qr(qr_OLDCREATEBITMAP_ARGS) )
28208 {
28209 std::swap(w, h);
28210 }
28211
28212 1509497 return create_user_bitmap_ex(h,w);
28213 }
28214
28215 1509497 uint32_t FFScript::create_user_bitmap_ex(int32_t w, int32_t h)
28216 {
28217 1509497 auto bmp = user_bitmaps.create();
28218
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1509497 times.
1509497 if (!bmp)
28219 return 0;
28220
28221 1509497 bmp->width = w;
28222 1509497 bmp->height = h;
28223 1509497 bmp->u_bmp = create_bitmap_ex(8,w,h);
28224 1509497 clear_bitmap(bmp->u_bmp);
28225 1509497 return bmp->id;
28226 1509497 }
28227
28228 21102680 bool FFScript::doesResolveToScreenBitmap(int32_t bitmap_id)
28229 {
28230
2/2
✓ Branch 0 taken 11414644 times.
✓ Branch 1 taken 9688036 times.
21102680 if (bitmap_id == rtSCREEN)
28231 9688036 return true;
28232
28233
2/2
✓ Branch 0 taken 12946 times.
✓ Branch 1 taken 11401698 times.
11414644 if (bitmap_id == -2)
28234 {
28235 12946 int curr_rt = zscriptDrawingRenderTarget->GetCurrentRenderTarget();
28236
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12946 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12946 if (curr_rt >= 0 && curr_rt < 7)
28237 return false;
28238
28239 12946 return true;
28240 }
28241
28242 11401698 return false;
28243 21102680 }
28244
28245 21102680 bool FFScript::doesResolveToDeprecatedSystemBitmap(int32_t bitmap_id)
28246 {
28247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21102680 times.
21102680 switch (bitmap_id)
28248 {
28249 case rtBMP0:
28250 case rtBMP1:
28251 case rtBMP2:
28252 case rtBMP3:
28253 case rtBMP4:
28254 case rtBMP5:
28255 case rtBMP6:
28256 {
28257 return true;
28258 }
28259 }
28260
28261
2/2
✓ Branch 0 taken 21089734 times.
✓ Branch 1 taken 12946 times.
21102680 if (bitmap_id == -2)
28262 {
28263 12946 int curr_rt = zscriptDrawingRenderTarget->GetCurrentRenderTarget();
28264
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12946 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12946 if (curr_rt >= 0 && curr_rt < 7)
28265 return true;
28266 12946 }
28267
28268 21102680 return false;
28269 21102680 }
28270
28271 66997310 BITMAP* FFScript::GetScriptBitmap(int32_t id, BITMAP* screen_bmp, bool skipError)
28272 {
28273
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 66996830 times.
✓ Branch 2 taken 480 times.
66997310 switch (id - 10)
28274 {
28275 case rtSCREEN:
28276 480 return screen_bmp;
28277
28278 case rtBMP0:
28279 case rtBMP1:
28280 case rtBMP2:
28281 case rtBMP3:
28282 case rtBMP4:
28283 case rtBMP5:
28284 case rtBMP6: //old system bitmaps (render targets)
28285 {
28286 return zscriptDrawingRenderTarget->GetBitmapPtr(id - 10);
28287 }
28288 }
28289
28290
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66996830 times.
66996830 if (auto bitmap = checkBitmap(id, true, skipError))
28291 66996830 return bitmap->u_bmp;
28292
28293 return nullptr;
28294 66997310 }
28295
28296 450 uint32_t FFScript::get_free_bitmap(bool skipError)
28297 {
28298 450 auto bmp = user_bitmaps.create(skipError);
28299
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 450 times.
450 if (!bmp)
28300 return 0;
28301 450 return bmp->id;
28302 450 }
28303
28304 3512 void FFScript::do_deallocate_bitmap()
28305 {
28306
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3512 times.
3512 if (ZScriptVersion::gc())
28307 return;
28308
28309
1/2
✓ Branch 0 taken 3512 times.
✗ Branch 1 not taken.
3512 if(isSystemBitref(GET_REF(bitmapref)))
28310 {
28311 return; //Don't attempt to deallocate system bitmaps!
28312 }
28313
28314 // Bitmaps are not deallocated right away, but deferred until the next call to scb.update()
28315
1/2
✓ Branch 0 taken 3512 times.
✗ Branch 1 not taken.
3512 if (auto b = checkBitmap(GET_REF(bitmapref), false, true))
28316 3512 b->free_obj();
28317 3512 }
28318
28319 3658 bool FFScript::isSystemBitref(int32_t ref)
28320 {
28321
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 switch(ref-10)
28322 {
28323 case rtSCREEN:
28324 case rtBMP0:
28325 case rtBMP1:
28326 case rtBMP2:
28327 case rtBMP3:
28328 case rtBMP4:
28329 case rtBMP5:
28330 case rtBMP6:
28331 return true;
28332 }
28333 3658 return false;
28334 3658 }
28335
28336 ///----------------------------------------------------------------------------------------------------
28337
28338 2197 int32_t FFScript::GetQuestVersion()
28339 {
28340 2197 return QHeader.zelda_version;
28341 }
28342 729 int32_t FFScript::GetQuestBuild()
28343 {
28344 729 return QHeader.build;
28345 }
28346 int32_t FFScript::GetQuestSectionVersion(int32_t section)
28347 {
28348 return QHeader.zelda_version;
28349 }
28350
28351 19 int32_t FFScript::GetDefaultWeaponSprite(int32_t wpn_id)
28352 {
28353
2/63
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✓ Branch 49 taken 10 times.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
19 switch (wpn_id)
28354 {
28355 case wNone:
28356 return 0;
28357
28358 case wSword: return 0;
28359 case wBeam: return 1;
28360 case wBrang: return 4;
28361 case wBomb: return 9;
28362 case wSBomb: return 75;
28363 case wLitBomb: return 7;
28364 case wLitSBomb: return 8;
28365 case wArrow: return 10;
28366 case wRefArrow: return 10;
28367 case wFire: return 12;
28368 case wRefFire: return 12;
28369 case wRefFire2: return 12;
28370 case wWhistle: return 45; //blank, unused misc sprite
28371 case wBait: return 14;
28372 case wWand: return 15;
28373 case wMagic: return 16;
28374 case wCatching: return 45; //blank, unused misc sprite
28375 case wWind: return 13;
28376 case wRefMagic: return 16;
28377 case wRefFireball: return 17;
28378 case wRefRock: return 18;
28379 case wHammer: return 25;
28380 case wHookshot: return 26;
28381 case wHSHandle: return 28;
28382 case wHSChain: return 27;
28383 case wSSparkle: return 29;
28384 case wFSparkle: return 32;
28385 case wSmack: return 33;
28386 case wPhantom: return -1;
28387 case wCByrna: return 87;
28388 case wRefBeam: return 1;
28389 case wStomp: return 45; //blank, unused misc sprite
28390 case lwMax: return 45; //blank, unused misc sprite
28391 case wScript1: { if ( get_qr(qr_WRITING_NPC_WEAPON_UNIQUE_SPRITES ) ) return 246; else return 0; }
28392 case wScript2: { if ( get_qr(qr_WRITING_NPC_WEAPON_UNIQUE_SPRITES ) ) return 247; else return 0; }
28393 case wScript3: { if ( get_qr(qr_WRITING_NPC_WEAPON_UNIQUE_SPRITES ) ) return 248; else return 0; }
28394 case wScript4: { if ( get_qr(qr_WRITING_NPC_WEAPON_UNIQUE_SPRITES ) ) return 249; else return 0; }
28395 case wScript5: { if ( get_qr(qr_WRITING_NPC_WEAPON_UNIQUE_SPRITES ) ) return 250; else return 0; }
28396 case wScript6: { if ( get_qr(qr_WRITING_NPC_WEAPON_UNIQUE_SPRITES ) ) return 251; else return 0; }
28397 case wScript7: { if ( get_qr(qr_WRITING_NPC_WEAPON_UNIQUE_SPRITES ) ) return 252; else return 0; }
28398 case wScript8: { if ( get_qr(qr_WRITING_NPC_WEAPON_UNIQUE_SPRITES ) ) return 253; else return 0; }
28399 case wScript9: { if ( get_qr(qr_WRITING_NPC_WEAPON_UNIQUE_SPRITES ) ) return 254; else return 0; }
28400 case wScript10: { if ( get_qr(qr_WRITING_NPC_WEAPON_UNIQUE_SPRITES ) ) return 255; else return 0; }
28401
28402 case wIce: return 83;
28403 //Cannot use any of these weapons yet.
28404 //return -1;
28405
28406 case wEnemyWeapons:
28407 9 case ewFireball: return 17;
28408
28409 case ewArrow: return 19;
28410 case ewBrang: return 4;
28411 10 case ewSword: return 20;
28412 case ewRock: return 18;
28413 case ewMagic: return 21;
28414 case ewBomb: return 78;
28415 case ewSBomb: return 79;
28416 case ewLitBomb: return 76;
28417 case ewLitSBomb: return 77;
28418 case ewFireTrail: return 80;
28419 case ewFlame: return 35;
28420 case ewWind: return 36;
28421 case ewFlame2: return 81;
28422 case ewFlame2Trail: return 82;
28423 case ewIce: return 83;
28424 case ewFireball2: return 17; //fireball (rising)
28425
28426
28427 default: return -1; //No assign.
28428
28429 }
28430 19 }
28431
28432 19 int32_t FFScript::GetDefaultWeaponSFX(int32_t wpn_id)
28433 {
28434
2/6
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 9 times.
19 switch (wpn_id)
28435 {
28436 case ewFireTrail:
28437 case ewFlame:
28438 case ewFlame2Trail:
28439 case ewFlame2:
28440 return WAV_FIRE; break;
28441 case ewWind:
28442 case ewMagic:
28443 return WAV_WAND; break;
28444 case ewIce:
28445 return WAV_ZN1ICE; break;
28446 case ewRock:
28447 return WAV_ZN1ROCK; break;
28448 case ewFireball2:
28449 case ewFireball:
28450 9 return WAV_ZN1FIREBALL; break;
28451 }
28452 10 return -1; //no assign
28453 19 }
28454
28455 void FFScript::do_bmpcollision()
28456 {
28457 int32_t bmpref = SH::read_stack(ri->sp + 5);
28458 int32_t maskbmpref = SH::read_stack(ri->sp + 4);
28459 int32_t x = SH::read_stack(ri->sp + 3) / 10000;
28460 int32_t y = SH::read_stack(ri->sp + 2) / 10000;
28461 int32_t checkCol = SH::read_stack(ri->sp + 1) / 10000;
28462 int32_t maskCol = SH::read_stack(ri->sp + 0) / 10000;
28463 BITMAP *checkbit = FFCore.GetScriptBitmap(bmpref, screen, true);
28464 BITMAP *maskbit = FFCore.GetScriptBitmap(maskbmpref, screen, true);
28465 if(!(checkbit && maskbit))
28466 {
28467 set_register(sarg1, -10000);
28468 char buf1[16];
28469 char buf2[16];
28470 zc_itoa(bmpref, buf1);
28471 zc_itoa(maskbmpref, buf2);
28472 Z_scripterrlog("Invalid bitmap%s passed to 'bitmap->CountColor()': %s%s%s\n",
28473 (checkbit || maskbit) ? "" : "s", checkbit ? "" : buf1,
28474 (checkbit || maskbit) ? "" : ", ", maskbit ? "" : buf2);
28475 return;
28476 }
28477 int32_t ret = countColor(checkbit, maskbit, x, y, checkCol, maskCol);
28478 set_register(sarg1, ret*10000);
28479 }
28480
28481
28482 7237302 int32_t FFScript::loadMapData()
28483 {
28484 7237302 int32_t map = (GET_D(rINDEX) / 10000);
28485 7237302 int32_t screen = (GET_D(rINDEX2)/10000);
28486
2/2
✓ Branch 0 taken 7237282 times.
✓ Branch 1 taken 20 times.
7237302 int32_t indx = (zc_max((map)-1,0) * MAPSCRS + screen);
28487
3/4
✓ Branch 0 taken 7237282 times.
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7237282 times.
7237302 if ( map < 1 || map > map_count )
28488 {
28489 20 Z_scripterrlog("Invalid Map ID passed to Game->LoadMapData: %d\n", map);
28490 20 ri->mapdataref = MAX_SIGNED_32;
28491 20 }
28492
2/4
✓ Branch 0 taken 7237282 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7237282 times.
7237282 else if ( screen < 0 || screen > 129 ) //0x00 to 0x81 -Z
28493 {
28494 Z_scripterrlog("Invalid Screen Index passed to Game->LoadMapData: %d\n", screen);
28495 ri->mapdataref = MAX_SIGNED_32;
28496 }
28497 7237282 else ri->mapdataref = indx;
28498 7237302 return ri->mapdataref;
28499 }
28500
28501 // Called when leaving a screen; deallocate arrays created by FFCs that aren't carried over
28502 13697902 void FFScript::deallocateArray(int32_t ptrval)
28503 {
28504
1/2
✓ Branch 0 taken 13697902 times.
✗ Branch 1 not taken.
13697902 CHECK(!ZScriptVersion::gc_arrays());
28505
28506
1/2
✓ Branch 0 taken 13697902 times.
✗ Branch 1 not taken.
13697902 if(ptrval == 0)
28507 return;
28508
2/4
✓ Branch 0 taken 13697902 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 13697902 times.
13697902 if(ptrval==0 || ptrval >= NUM_ZSCRIPT_ARRAYS)
28509 scripting_log_error_with_context("Script tried to deallocate memory at invalid address {}", ptrval);
28510
1/2
✓ Branch 0 taken 13697902 times.
✗ Branch 1 not taken.
13697902 else if(ptrval<0)
28511 scripting_log_error_with_context("Script tried to deallocate memory at object-based address {}", ptrval);
28512 else
28513 {
28514
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13697902 times.
13697902 if(arrayOwner[ptrval].specOwned) return; //ignore this deallocation
28515
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13697902 times.
13697902 if(arrayOwner[ptrval].specCleared) return;
28516 13697902 arrayOwner[ptrval].clear();
28517
28518
1/2
✓ Branch 0 taken 13697902 times.
✗ Branch 1 not taken.
13697902 if(!localRAM[ptrval].Valid())
28519 scripting_log_error_with_context("Script tried to deallocate memory that was not allocated at address {}", ptrval);
28520 else
28521 {
28522
2/2
✓ Branch 0 taken 13697899 times.
✓ Branch 1 taken 3 times.
13697902 if (localRAM[ptrval].HoldsObjects())
28523 {
28524 3 auto&& aptr = localRAM[ptrval];
28525
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
5 for (int i = 0; i < aptr.Size(); i++)
28526 {
28527 2 int id = aptr[i];
28528 2 script_object_ref_dec(id);
28529 2 }
28530 3 }
28531 13697902 localRAM[ptrval].Clear();
28532 }
28533 }
28534 13697902 }
28535
28536 2681734 int32_t FFScript::get_screen_d(int32_t index1, int32_t index2)
28537 {
28538
3/4
✓ Branch 0 taken 2681734 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 2681728 times.
2681734 if(index2 < 0 || index2 > 7)
28539 {
28540 6 scripting_log_error_with_context("You were trying to reference an out-of-bounds array index for a screen's D[] array ({}); valid indices are from 0 to 7.", index1);
28541 6 return 0;
28542 }
28543
2/4
✓ Branch 0 taken 2681728 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2681728 times.
2681728 if (index1 < 0 || index1 >= game->screen_d.size())
28544 {
28545 scripting_log_error_with_context("You were trying to reference an out-of-bounds screen for a D[] array ({}); valid indices are from 0 to %u.", index1, game->screen_d.size() - 1);
28546 return 0;
28547 }
28548
28549 2681728 return game->screen_d[index1][index2];
28550 2681734 }
28551
28552 54512 void FFScript::set_screen_d(int32_t index1, int32_t index2, int32_t val)
28553 {
28554
2/4
✓ Branch 0 taken 54512 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 54512 times.
54512 if(index2 < 0 || index2 > 7)
28555 {
28556 scripting_log_error_with_context("You were trying to reference an out-of-bounds array index for a screen's D[] array ({}); valid indices are from 0 to 7.", index1);
28557 return;
28558 }
28559
2/4
✓ Branch 0 taken 54512 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 54512 times.
54512 if (index1 < 0 || index1 >= game->screen_d.size())
28560 {
28561 scripting_log_error_with_context("You were trying to reference an out-of-bounds screen for a D[] array ({}); valid indices are from 0 to %u.", index1, game->screen_d.size() - 1);
28562 return;
28563 }
28564
28565 54512 game->screen_d[index1][index2] = val;
28566 54512 }
28567
28568 void FFScript::do_zapout()
28569 {
28570 zapout();
28571 }
28572
28573 void FFScript::do_zapin(){ zapin(); }
28574
28575 void FFScript::do_openscreen() { openscreen(); }
28576 void FFScript::do_closescreen() { closescreen(); }
28577 void FFScript::do_openscreenshape()
28578 {
28579 int32_t shape = get_register(sarg1) / 10000;
28580 if(shape < 0 || shape >= bosMAX)
28581 {
28582 Z_scripterrlog("Invalid shape passed to %s! Valid range %d to %d. Using 'Circle' shape.\n", "Screen->OpeningWipe(int32_t)", 0, bosMAX-1);
28583 shape = bosCIRCLE;
28584 }
28585 openscreen(shape);
28586 }
28587 void FFScript::do_closescreenshape()
28588 {
28589 int32_t shape = get_register(sarg1) / 10000;
28590 if(shape < 0 || shape >= bosMAX)
28591 {
28592 Z_scripterrlog("Invalid shape passed to %s! Valid range %d to %d. Using 'Circle' shape.\n", "Screen->ClosingWipe(int32_t)", 0, bosMAX-1);
28593 shape = bosCIRCLE;
28594 }
28595 closescreen(shape);
28596 }
28597 void FFScript::do_wavyin() { wavyin(); }
28598 void FFScript::do_wavyout() { wavyout(false); }
28599
28600
28601 void FFScript::do_triggersecret(const bool v)
28602 {
28603 int32_t ID = vbound((SH::get_arg(sarg1, v) / 10000), 0, 255);
28604 mapscr *s = hero_scr;
28605 //Convert a flag type to a secret type.
28606 int32_t ft = combo_trigger_flag_to_secret_combo_index(ID);
28607 if (ft != -1)
28608 {
28609 for(int32_t iter=0; iter<2; ++iter)
28610 {
28611 for ( int32_t q = 0; q < 176; q++ )
28612 {
28613 //Placed flags
28614 if ( iter == 1 )
28615 {
28616 if ( s->sflag[q] == ID ) {
28617 auto rpos_handle = get_rpos_handle_for_screen(s->screen, 0, q);
28618 screen_combo_modify_preroutine(rpos_handle);
28619 s->data[q] = s->secretcombo[ft];
28620 s->cset[q] = s->secretcset[ft];
28621 s->sflag[q] = s->secretflag[ft];
28622 screen_combo_modify_postroutine(rpos_handle);
28623 }
28624 }
28625 //Inherent flags
28626 else
28627 {
28628 if ( combobuf[s->data[q]].flag == ID ) {
28629 auto rpos_handle = get_rpos_handle_for_screen(s->screen, 0, q);
28630 screen_combo_modify_preroutine(rpos_handle);
28631 s->data[q] = s->secretcombo[ft];
28632 s->cset[q] = s->secretcset[ft];
28633 screen_combo_modify_postroutine(rpos_handle);
28634 }
28635
28636 }
28637 }
28638 }
28639 }
28640
28641 }
28642
28643 2004 void FFScript::do_setMIDI_volume(int32_t m)
28644 {
28645 2004 master_volume(-1,(vbound(m,0,255)));
28646 2004 }
28647 2004 void FFScript::do_setMusic_volume(int32_t m)
28648 {
28649 2004 emusic_volume = vbound(m,0,255);
28650 2004 }
28651 2004 void FFScript::do_setDIGI_volume(int32_t m)
28652 {
28653 2004 master_volume((vbound(m,0,255)),-1);
28654 2004 }
28655 void FFScript::do_setSFX_volume(int32_t m)
28656 {
28657 sfx_volume = m;
28658 }
28659 void FFScript::do_setSFX_pan(int32_t m)
28660 {
28661 pan_style = vbound(m,0,3);
28662 }
28663 8 int32_t FFScript::do_getMIDI_volume()
28664 {
28665 8 return ((int32_t)midi_volume);
28666 }
28667 8 int32_t FFScript::do_getMusic_volume()
28668 {
28669 8 return ((int32_t)emusic_volume);
28670 }
28671 8 int32_t FFScript::do_getDIGI_volume()
28672 {
28673 8 return ((int32_t)digi_volume);
28674 }
28675 int32_t FFScript::do_getSFX_volume()
28676 {
28677 return ((int32_t)sfx_volume);
28678 }
28679 int32_t FFScript::do_getSFX_pan()
28680 {
28681 return ((int32_t)pan_style);
28682 }
28683
28684
28685 //Change Game Over Screen Values
28686 void FFScript::FFSetSaveScreenSetting()
28687 {
28688
28689 int32_t indx = get_register(sarg1) / 10000;
28690 int32_t value = get_register(sarg2) / 10000; //bounded in zelda.cpp
28691 if(indx < 0 || indx > 11)
28692 set_register(sarg1, -10000);
28693 else
28694 SetSaveScreenSetting(indx, value);
28695 }
28696
28697
28698
28699 void FFScript::FFChangeSubscreenText()
28700 {
28701
28702 int32_t index = get_register(sarg1) / 10000;
28703 int32_t arrayptr = get_register(sarg2);
28704
28705 if ( index < 0 || index > 3 )
28706 {
28707 al_trace("The index supplied to Game->SetSubscreenText() is invalid. The index specified was: %d /n", index);
28708 return;
28709 }
28710
28711 string filename_str;
28712 ArrayH::getString(arrayptr, filename_str, 73);
28713 ChangeSubscreenText(index,filename_str.c_str());
28714 }
28715
28716 55 void FFScript::SetItemMessagePlayed(int32_t itm)
28717 {
28718 55 game->item_messages_played[itm] = 1;
28719 55 }
28720 81 bool FFScript::GetItemMessagePlayed(int32_t itm)
28721 {
28722 81 return ((game->item_messages_played[itm] ) ? true : false);
28723 }
28724
28725 int32_t FFScript::getQRBit(int32_t rule)
28726 {
28727 return ( get_qr(rule) ? 1 : 0 );
28728 }
28729
28730 27141373 void FFScript::setHeroAction(int32_t a)
28731 {
28732 27141373 FF_hero_action = vbound(a, 0, 255);
28733 27141373 }
28734
28735 112790051 int32_t FFScript::getHeroAction()
28736 {
28737 112790051 int32_t special_action = Hero.getAction2();
28738
2/2
✓ Branch 0 taken 849143 times.
✓ Branch 1 taken 111940908 times.
112790051 if ( special_action != -1 ) return special_action; //spin, dive, charge
28739 111940908 else return FF_hero_action; //everything else
28740 112790051 }
28741
28742 1154 void FFScript::init(bool for_continue)
28743 {
28744 1154 apply_qr_rules();
28745 1154 eventData.clear();
28746 1154 countGenScripts();
28747 // Some scripts can run even before ~Init (but only if qr_OLD_INIT_SCRIPT_TIMING is on), so figure out
28748 // the global register types ahead of time.
28749 1154 markGlobalRegisters();
28750
2/2
✓ Branch 0 taken 11540 times.
✓ Branch 1 taken 1154 times.
12694 for ( int32_t q = 0; q < wexLast; q++ ) warpex[q] = 0;
28751 1154 temp_no_stepforward = 0;
28752 1154 nostepforward = 0;
28753 1154 numscriptdraws = 0;
28754 1154 skipscriptdraws = false;
28755 1154 max_ff_rules = qr_MAX;
28756 1154 coreflags = 0;
28757 1154 skip_ending_credits = 0;
28758 1154 music_update_cond = 0;
28759 1154 music_update_flags = 0;
28760 //quest_format : is this properly initialised?
28761
2/2
✓ Branch 0 taken 78472 times.
✓ Branch 1 taken 1154 times.
79626 for ( int32_t q = 0; q < susptLAST; q++ ) { system_suspend[q] = 0; }
28762
28763 1154 usr_midi_volume = midi_volume;
28764 1154 usr_digi_volume = digi_volume;
28765 1154 usr_sfx_volume = sfx_volume;
28766 1154 usr_music_volume = emusic_volume;
28767
28768 1154 usr_panstyle = pan_style;
28769 1154 FF_hero_action = 0;
28770 1154 enemy_removal_point[spriteremovalY1] = -32767;
28771 1154 enemy_removal_point[spriteremovalY2] = 32767;
28772 1154 enemy_removal_point[spriteremovalX1] = -32767;
28773 1154 enemy_removal_point[spriteremovalX2] = 32767;
28774 1154 enemy_removal_point[spriteremovalZ1] = -32767;
28775 1154 enemy_removal_point[spriteremovalZ2] = 32767;
28776
28777
2/2
✓ Branch 0 taken 4616 times.
✓ Branch 1 taken 1154 times.
5770 for ( int32_t q = 0; q < 4; q++ )
28778 {
28779 4616 FF_screenbounds[q] = 0;
28780 4616 FF_screen_dimensions[q] = 0;
28781 4616 FF_subscreen_dimensions[q] = 0;
28782 4616 FF_eweapon_removal_bounds[q] = 0;
28783 4616 FF_lweapon_removal_bounds[q] = 0;
28784 4616 }
28785
2/2
✓ Branch 0 taken 11540 times.
✓ Branch 1 taken 1154 times.
12694 for ( int32_t q = 0; q < FFSCRIPTCLASS_CLOCKS; q++ )
28786 {
28787 11540 FF_clocks[q] = 0;
28788 11540 }
28789
2/2
✓ Branch 0 taken 23080 times.
✓ Branch 1 taken 1154 times.
24234 for ( int32_t q = 0; q < SCRIPT_DRAWING_RULES; q++ )
28790 {
28791 23080 ScriptDrawingRules[q] = 0;
28792 23080 }
28793
2/2
✓ Branch 0 taken 6924 times.
✓ Branch 1 taken 1154 times.
8078 for ( int32_t q = 0; q < NUM_USER_MIDI_OVERRIDES; q++ )
28794 {
28795 6924 FF_UserMidis[q] = 0;
28796 6924 }
28797 1154 subscreen_scroll_speed = 0; //make a define for a default and read quest override! -Z
28798 1154 kb_typing_mode = false;
28799 //clearRunningItemScripts();
28800 1154 ScrollingScreensAll.clear();
28801 1154 memset(ScrollingData, 0, sizeof(int32_t) * SZ_SCROLLDATA);
28802 1154 ScrollingData[SCROLLDATA_DIR] = -1;
28803 1154 user_rng_init();
28804
2/2
✓ Branch 0 taken 714 times.
✓ Branch 1 taken 440 times.
1154 if (for_continue)
28805 714 clear_script_engine_data_for_continue();
28806 440 else clear_script_engine_data();
28807 1154 script_debug_handles.clear();
28808 1154 runtime_script_debug_handle = nullptr;
28809 1154 }
28810
28811 326 void FFScript::shutdown()
28812 {
28813 326 scriptEngineDatas.clear();
28814 326 objectRAM.clear();
28815 326 script_objects.clear();
28816 326 }
28817
28818 12 void FFScript::SetFFEngineFlag(int32_t flag, bool state)
28819 {
28820
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if ( state ) { coreflags |= flag; }
28821 else coreflags &= ~flag;
28822 12 }
28823
28824 void FFScript::setSubscreenScrollSpeed(byte n)
28825 {
28826 subscreen_scroll_speed = n;
28827 }
28828
28829 int32_t FFScript::getSubscreenScrollSpeed()
28830 {
28831 return (int32_t)subscreen_scroll_speed;
28832 }
28833
28834 void FFScript::do_greyscale(const bool v)
28835 {
28836 // This has been removed.
28837 }
28838
28839 void FFScript::do_monochromatic(const bool v)
28840 {
28841 // This has been removed.
28842 }
28843
28844 10680 static int convert_6bit_to_8bit_color_shift_arg(int v)
28845 {
28846 10680 int va = abs(v);
28847
2/2
✓ Branch 0 taken 10677 times.
✓ Branch 1 taken 3 times.
10680 if (va < 64)
28848 10677 return _rgb_scale_6[va] * sign(v);
28849
28850 3 int vdiv = va / 63;
28851 3 int vmod = va % 63;
28852 3 return (vdiv * 255 + _rgb_scale_6[vmod]) * sign(v);
28853 10680 }
28854
28855 void FFScript::gfxmonohue()
28856 {
28857 int32_t r = SH::read_stack(ri->sp + 3) / 10000;
28858 int32_t g = SH::read_stack(ri->sp + 2) / 10000;
28859 int32_t b = SH::read_stack(ri->sp + 1) / 10000;
28860 if (!scripting_use_8bit_colors)
28861 {
28862 r = convert_6bit_to_8bit_color_shift_arg(r);
28863 g = convert_6bit_to_8bit_color_shift_arg(g);
28864 b = convert_6bit_to_8bit_color_shift_arg(b);
28865 }
28866 bool m = (SH::read_stack(ri->sp + 0) / 10000);
28867 doGFXMonohue(r,g,b,m);
28868 }
28869
28870 66 void FFScript::clearTint()
28871 {
28872 66 doClearTint();
28873 66 }
28874
28875 3560 void FFScript::Tint()
28876 {
28877 3560 int32_t r = SH::read_stack(ri->sp + 2) / 10000;
28878 3560 int32_t g = SH::read_stack(ri->sp + 1) / 10000;
28879 3560 int32_t b = SH::read_stack(ri->sp + 0) / 10000;
28880
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3560 times.
3560 if (!scripting_use_8bit_colors)
28881 {
28882 3560 r = convert_6bit_to_8bit_color_shift_arg(r);
28883 3560 g = convert_6bit_to_8bit_color_shift_arg(g);
28884 3560 b = convert_6bit_to_8bit_color_shift_arg(b);
28885 3560 }
28886 3560 doTint(r,g,b);
28887 3560 }
28888
28889 void FFScript::do_fx_zap(const bool v)
28890 {
28891 int32_t out = SH::get_arg(sarg1, v);
28892
28893 if ( out ) { FFScript::do_zapout(); }
28894 else FFScript::do_zapin();
28895 }
28896
28897 void FFScript::do_fx_wavy(const bool v)
28898 {
28899 int32_t out = SH::get_arg(sarg1, v);
28900
28901 if ( out ) { FFScript::do_wavyout(); }
28902 else FFScript::do_wavyin();
28903 }
28904
28905 541271523 int32_t FFScript::getQuestHeaderInfo(int32_t type)
28906 {
28907 541271523 return quest_format[type];
28908 }
28909
28910 string get_filestr(const bool relative, bool is_file) //Used for 'FileSystem' functions.
28911 {
28912 int32_t strptr = get_register(sarg1);
28913 string user_path;
28914 ArrayH::getString(strptr, user_path, 512);
28915
28916 if (!relative)
28917 {
28918 // Kill leading '/'
28919 size_t first = user_path.find_first_not_of('/');
28920 if (first != string::npos)
28921 user_path = user_path.substr(first, string::npos);
28922
28923 // Kill trailing '/'
28924 size_t last = user_path.find_last_not_of('/');
28925 if (last != string::npos)
28926 user_path = user_path.substr(0, last + 1);
28927
28928 return user_path;
28929 }
28930
28931 if (auto r = parse_user_path(user_path, is_file); !r)
28932 {
28933 scripting_log_error_with_context("Error: {}", r.error());
28934 return "";
28935 } else return r.value();
28936 }
28937
28938 void FFScript::do_checkdir(const bool is_dir)
28939 {
28940 string resolved_path = get_filestr(get_qr(qr_BITMAP_AND_FILESYSTEM_PATHS_ALWAYS_RELATIVE), false);
28941 set_register(sarg1, !resolved_path.empty() && checkPath(resolved_path.c_str(), is_dir) ? 10000 : 0);
28942 }
28943
28944 void FFScript::do_fs_remove()
28945 {
28946 string resolved_path = get_filestr(true, true);
28947 set_register(sarg1, !resolved_path.empty() && remove(resolved_path.c_str()) ? 0 : 10000);
28948 }
28949
28950 111 void FFScript::Play_Level_Music()
28951 {
28952 111 int32_t m = hero_scr->screen_midi;
28953
28954
1/6
✓ Branch 0 taken 111 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
111 switch(m)
28955 {
28956 case -2:
28957 music_stop();
28958 break;
28959
28960 case -1:
28961 111 play_DmapMusic();
28962 111 break;
28963
28964 case 1:
28965 jukebox(ZC_MIDI_OVERWORLD);
28966 break;
28967
28968 case 2:
28969 jukebox(ZC_MIDI_DUNGEON);
28970 break;
28971
28972 case 3:
28973 jukebox(ZC_MIDI_LEVEL9);
28974 break;
28975
28976 default:
28977 if(m>=4 && m<4+MAXCUSTOMMIDIS)
28978 jukebox(m+MIDIOFFSET_MAPSCR);
28979 else
28980 music_stop();
28981 }
28982 111 }
28983
28984 100 static void warp_ex(int args[wexLast])
28985 {
28986
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
100 if ( ((unsigned)args[1]) >= MAXDMAPS )
28987 Z_scripterrlog("Invalid DMap ID (%d) passed to WarpEx(). Aborting.\n", args[1]);
28988
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
100 else if ( ((unsigned)args[2]) >= MAPSCRS )
28989 Z_scripterrlog("Invalid Screen Index (%d) passed to WarpEx(). Aborting.\n", args[2]);
28990
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
100 else if ( map_screen_index(DMaps[args[1]].map, args[2] + DMaps[args[1]].xoff) >= (int32_t)TheMaps.size() )
28991 Z_scripterrlog("Invalid destination passed to WarpEx(). Aborting.\n");
28992 else
28993 {
28994
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
100 if(get_qr(qr_OLD_BROKEN_WARPEX_MUSIC))
28995 {
28996
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 96 times.
100 SETFLAG(args[wexFlags],warpFlagFORCECONTINUEMUSIC,args[wexFlags]&warpFlagFORCERESETMUSIC);
28997 100 TOGGLEFLAG(args[wexFlags],warpFlagFORCERESETMUSIC);
28998 100 }
28999 100 memcpy(FFCore.warpex, args, sizeof(FFCore.warpex));
29000 100 FFCore.warpex[wexActive] = 1;
29001 }
29002 100 }
29003
29004 void FFScript::do_warp_ex()
29005 {
29006 int num_args = sarg1 / 10000;
29007 if (num_args < 8 || unsigned(num_args) > wexActive)
29008 {
29009 scripting_log_error_with_context("Invalid parameter count %d!", num_args);
29010 return;
29011 }
29012 int args[wexLast] = {0};
29013 for (int q = 0; q < num_args; ++q)
29014 args[q] = SH::read_stack(ri->sp + (num_args - q - 1)) / 10000;
29015 warp_ex(args);
29016 }
29017
29018 100 void FFScript::do_warp_ex_array()
29019 {
29020 100 int32_t zscript_array_ptr = get_register(sarg1);
29021 100 ArrayManager am(zscript_array_ptr);
29022
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
100 if(am.invalid()) return;
29023 100 int32_t zscript_array_size = am.size();
29024
1/2
✓ Branch 0 taken 100 times.
✗ Branch 1 not taken.
100 switch(zscript_array_size)
29025 {
29026 case 8: // {int32_t type, int32_t dmap, int32_t screen, int32_t x, int32_t y, int32_t effect, int32_t sound, int32_t flags}
29027 case 9: // {int32_t type, int32_t dmap, int32_t screen, int32_t x, int32_t y, int32_t effect, int32_t sound, int32_t flags, int32_t dir}
29028 {
29029 100 int args[wexLast] = {0};
29030
2/2
✓ Branch 0 taken 800 times.
✓ Branch 1 taken 100 times.
900 for ( int32_t q = 0; q < 8; q++ )
29031 800 args[q] = (am.get(q)/10000);
29032
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 74 times.
100 args[wexDir] = zscript_array_size < 9 ? -1 : (am.get(8)/10000);
29033 100 warp_ex(args);
29034 100 break;
29035 }
29036
29037 default:
29038 {
29039 scripting_log_error_with_context("Array supplied is the wrong size! The array size was: %d, and valid sizes are 8 and 9.", zscript_array_size);
29040 break;
29041 }
29042 }
29043 100 }
29044
29045 ///////////////////////////////
29046 //* SCRIPT ENGINE FUNCTIONS *//
29047 ////////////////////////////////////////////////////////////////////////////
29048
29049 void FFScript::clearRunningItemScripts()
29050 {
29051 //for ( byte q = 0; q < 256; q++ ) runningItemScripts[q] = 0;
29052 }
29053
29054
29055 12142 void FFScript::warpScriptCheck()
29056 {
29057
2/2
✓ Branch 0 taken 596 times.
✓ Branch 1 taken 11546 times.
12142 if(get_qr(qr_SCRIPTDRAWSINWARPS))
29058 {
29059 596 FFCore.runWarpScripts(false);
29060 596 FFCore.runWarpScripts(true); //Waitdraw
29061 596 }
29062
3/4
✓ Branch 0 taken 844 times.
✓ Branch 1 taken 10702 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 844 times.
11546 else if(get_qr(qr_PASSIVE_SUBSCRIPT_RUNS_WHEN_GAME_IS_FROZEN) && doscript(ScriptType::ScriptedPassiveSubscreen))
29063 {
29064
1/2
✓ Branch 0 taken 844 times.
✗ Branch 1 not taken.
844 if(DMaps[cur_dmap].passive_sub_script != 0)
29065 ZScriptVersion::RunScript(ScriptType::ScriptedPassiveSubscreen, DMaps[cur_dmap].passive_sub_script, cur_dmap);
29066
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 844 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
844 if (waitdraw(ScriptType::ScriptedPassiveSubscreen) && DMaps[cur_dmap].passive_sub_script != 0 && doscript(ScriptType::ScriptedPassiveSubscreen))
29067 {
29068 ZScriptVersion::RunScript(ScriptType::ScriptedPassiveSubscreen, DMaps[cur_dmap].passive_sub_script, cur_dmap);
29069 waitdraw(ScriptType::ScriptedPassiveSubscreen) = false;
29070 }
29071 844 }
29072 12142 }
29073
29074 1192 void FFScript::runWarpScripts(bool waitdraw)
29075 {
29076
2/2
✓ Branch 0 taken 596 times.
✓ Branch 1 taken 596 times.
1192 if(waitdraw)
29077 {
29078
3/4
✓ Branch 0 taken 596 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 242 times.
✓ Branch 3 taken 354 times.
596 if ((!( FFCore.system_suspend[susptGLOBALGAME] )) && FFCore.waitdraw(ScriptType::Global, GLOBAL_SCRIPT_GAME))
29079 {
29080 354 ZScriptVersion::RunScript(ScriptType::Global, GLOBAL_SCRIPT_GAME, GLOBAL_SCRIPT_GAME);
29081 354 FFCore.waitdraw(ScriptType::Global, GLOBAL_SCRIPT_GAME) = false;
29082 354 }
29083
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 596 times.
596 if ( !FFCore.system_suspend[susptITEMSCRIPTENGINE] )
29084 {
29085 596 FFCore.itemScriptEngineOnWaitdraw();
29086 596 }
29087
2/6
✓ Branch 0 taken 596 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 596 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
596 if ( (!( FFCore.system_suspend[susptHEROACTIVE] )) && FFCore.waitdraw(ScriptType::Hero) && FFCore.getQuestHeaderInfo(vZelda) >= 0x255 )
29088 {
29089 ZScriptVersion::RunScript(ScriptType::Hero, SCRIPT_HERO_ACTIVE);
29090 FFCore.waitdraw(ScriptType::Hero) = false;
29091 }
29092
2/6
✓ Branch 0 taken 596 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 596 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
596 if ( (!( FFCore.system_suspend[susptDMAPSCRIPT] )) && FFCore.waitdraw(ScriptType::DMap) && FFCore.getQuestHeaderInfo(vZelda) >= 0x255 )
29093 {
29094 ZScriptVersion::RunScript(ScriptType::DMap, DMaps[cur_dmap].script,cur_dmap);
29095 FFCore.waitdraw(ScriptType::DMap) = false;
29096 }
29097
4/6
✓ Branch 0 taken 596 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 595 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
596 if ( (!( FFCore.system_suspend[susptDMAPSCRIPT] )) && FFCore.waitdraw(ScriptType::ScriptedPassiveSubscreen) && FFCore.getQuestHeaderInfo(vZelda) >= 0x255 )
29098 {
29099 1 ZScriptVersion::RunScript(ScriptType::ScriptedPassiveSubscreen, DMaps[cur_dmap].passive_sub_script,cur_dmap);
29100 1 FFCore.waitdraw(ScriptType::ScriptedPassiveSubscreen) = false;
29101 1 }
29102 //no doscript check here, becauseb of preload? Do we want to write doscript here? -Z 13th July, 2019
29103
2/4
✓ Branch 0 taken 596 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 596 times.
596 if (FFCore.getQuestHeaderInfo(vZelda) >= 0x255 && !FFCore.system_suspend[susptSCREENSCRIPTS])
29104 {
29105 1192 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
29106
3/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 590 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
596 if (scr->script != 0 && FFCore.waitdraw(ScriptType::Screen, scr->screen) && scr->preloadscript)
29107 {
29108 ZScriptVersion::RunScript(ScriptType::Screen, scr->script, scr->screen);
29109 FFCore.waitdraw(ScriptType::Screen, scr->screen) = 0;
29110 }
29111 596 });
29112 596 }
29113 596 }
29114 else
29115 {
29116
2/4
✓ Branch 0 taken 596 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 596 times.
596 if ((!( FFCore.system_suspend[susptGLOBALGAME] )) && FFCore.doscript(ScriptType::Global, GLOBAL_SCRIPT_GAME))
29117 {
29118 596 ZScriptVersion::RunScript(ScriptType::Global, GLOBAL_SCRIPT_GAME, GLOBAL_SCRIPT_GAME);
29119 596 }
29120
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 596 times.
596 if ( !FFCore.system_suspend[susptITEMSCRIPTENGINE] )
29121 {
29122 596 FFCore.itemScriptEngine();
29123 596 }
29124
4/6
✓ Branch 0 taken 596 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 564 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 32 times.
596 if ((!( FFCore.system_suspend[susptHEROACTIVE] )) && doscript(ScriptType::Hero) && FFCore.getQuestHeaderInfo(vZelda) >= 0x255)
29125 {
29126 32 ZScriptVersion::RunScript(ScriptType::Hero, SCRIPT_HERO_ACTIVE);
29127 32 }
29128
3/6
✓ Branch 0 taken 596 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 596 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 596 times.
596 if ( (!( FFCore.system_suspend[susptDMAPSCRIPT] )) && doscript(ScriptType::DMap) && FFCore.getQuestHeaderInfo(vZelda) >= 0x255 )
29129 {
29130 596 ZScriptVersion::RunScript(ScriptType::DMap, DMaps[cur_dmap].script,cur_dmap);
29131 596 }
29132
3/6
✓ Branch 0 taken 596 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 596 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 596 times.
596 if ( (!( FFCore.system_suspend[susptDMAPSCRIPT] )) && FFCore.doscript(ScriptType::ScriptedPassiveSubscreen) && FFCore.getQuestHeaderInfo(vZelda) >= 0x255 )
29133 {
29134 596 ZScriptVersion::RunScript(ScriptType::ScriptedPassiveSubscreen, DMaps[cur_dmap].passive_sub_script,cur_dmap);
29135 596 }
29136
2/4
✓ Branch 0 taken 596 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 596 times.
596 if (FFCore.getQuestHeaderInfo(vZelda) >= 0x255 && !FFCore.system_suspend[susptSCREENSCRIPTS])
29137 {
29138 1192 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
29139
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 590 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
596 if (scr->script != 0 && scr->preloadscript)
29140 {
29141 ZScriptVersion::RunScript(ScriptType::Screen, scr->script, scr->screen);
29142 }
29143 596 });
29144 596 }
29145 }
29146 1192 }
29147
29148 36287638 void FFScript::runF6Engine()
29149 {
29150
5/6
✓ Branch 0 taken 36285795 times.
✓ Branch 1 taken 1843 times.
✓ Branch 2 taken 59 times.
✓ Branch 3 taken 36285736 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 59 times.
36287638 if(!Quit && (GameFlags&GAMEFLAG_TRYQUIT) && !(GameFlags&GAMEFLAG_F6SCRIPT_ACTIVE))
29151 {
29152
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 47 times.
59 if(globalscripts[GLOBAL_SCRIPT_F6]->valid())
29153 {
29154 //Incase this was called mid-another script, store ref data
29155 12 push_ri();
29156 //
29157 12 clear_bitmap(f6_menu_buf);
29158 12 blit(framebuf, f6_menu_buf, 0, 0, 0, 0, framebuf->w, framebuf->h);
29159 12 initZScriptGlobalScript(GLOBAL_SCRIPT_F6);
29160 12 int32_t openingwipe = black_opening_count;
29161 12 int32_t openingshape = black_opening_shape;
29162 12 black_opening_count = 0; //No opening wipe during F6 menu
29163
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if(black_opening_shape==bosFADEBLACK) black_fade(0);
29164 12 GameFlags |= GAMEFLAG_F6SCRIPT_ACTIVE;
29165 //auto tmpDrawCommands = script_drawing_commands.pop_commands();
29166 12 pause_all_sfx();
29167
29168 12 auto& data = get_script_engine_data(ScriptType::Global, GLOBAL_SCRIPT_F6);
29169
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 while (data.doscript)
29170 {
29171 12 script_drawing_commands.Clear();
29172 12 load_control_state();
29173 12 ZScriptVersion::RunScript(ScriptType::Global, GLOBAL_SCRIPT_F6, GLOBAL_SCRIPT_F6);
29174
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (data.waitdraw)
29175 {
29176 ZScriptVersion::RunScript(ScriptType::Global, GLOBAL_SCRIPT_F6, GLOBAL_SCRIPT_F6);
29177 data.waitdraw = false;
29178 }
29179 //Draw
29180 12 clear_bitmap(framebuf);
29181
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if( !FFCore.system_suspend[susptCOMBOANIM] ) animate_combos();
29182 12 doScriptMenuDraws();
29183 //
29184 12 advanceframe(true,true,false);
29185
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if(Quit) break; //Something quit, end script running
29186 }
29187 12 resume_all_sfx();
29188 12 script_drawing_commands.Clear();
29189 //script_drawing_commands.push_commands(tmpDrawCommands);
29190 12 GameFlags &= ~GAMEFLAG_F6SCRIPT_ACTIVE;
29191 //Restore opening wipe
29192 12 black_opening_count = openingwipe;
29193 12 black_opening_shape = openingshape;
29194
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if(openingshape == bosFADEBLACK)
29195 {
29196 refreshTints();
29197 memcpy(tempblackpal, RAMpal, PAL_SIZE*sizeof(RGB));
29198 }
29199 //Restore script refinfo
29200 12 pop_ri();
29201 //
29202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if(!Quit)
29203 {
29204
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if(!get_qr(qr_NOCONTINUE))
29205 12 f_Quit(qQUIT);
29206 12 }
29207 12 }
29208
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
47 else if (unsigned(QMisc.savemenu_f6 - 1) < NUM_SAVE_MENUS && QMisc.save_menus[QMisc.savemenu_f6 - 1].is_valid())
29209 {
29210 GameFlags |= GAMEFLAG_F6SCRIPT_ACTIVE;
29211 QMisc.save_menus[QMisc.savemenu_f6 - 1].run();
29212 GameFlags &= ~GAMEFLAG_F6SCRIPT_ACTIVE;
29213 }
29214 47 else f_Quit(qQUIT);
29215 59 zc_readkey(KEY_F6);
29216 59 GameFlags &= ~GAMEFLAG_TRYQUIT;
29217 59 }
29218 36287638 }
29219 48 void FFScript::runOnDeathEngine()
29220 {
29221
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 17 times.
48 if(!playerscripts[SCRIPT_HERO_DEATH]->valid()) return; //No script to run
29222 17 clear_bitmap(script_menu_buf);
29223 17 blit(framebuf, script_menu_buf, 0, 0, 0, 0, framebuf->w, framebuf->h);
29224 17 initZScriptHeroScripts();
29225 17 GameFlags |= GAMEFLAG_SCRIPTMENU_ACTIVE;
29226 17 kill_sfx(); //No need to pause/resume; the player is dead.
29227 //auto tmpDrawCommands = script_drawing_commands.pop_commands();
29228
29229 17 auto& data = get_script_engine_data(ScriptType::Hero);
29230
4/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 818 times.
✓ Branch 2 taken 818 times.
✓ Branch 3 taken 17 times.
835 while (data.doscript && !Quit)
29231 {
29232 818 script_drawing_commands.Clear();
29233 818 load_control_state();
29234 818 ZScriptVersion::RunScript(ScriptType::Hero, SCRIPT_HERO_DEATH);
29235
1/2
✓ Branch 0 taken 818 times.
✗ Branch 1 not taken.
818 if (data.waitdraw)
29236 {
29237 ZScriptVersion::RunScript(ScriptType::Hero, SCRIPT_HERO_DEATH);
29238 data.waitdraw = false;
29239 }
29240 //Draw
29241 818 clear_bitmap(framebuf);
29242
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 818 times.
818 if( !FFCore.system_suspend[susptCOMBOANIM] ) animate_combos();
29243 818 doScriptMenuDraws();
29244 //
29245 818 advanceframe(true);
29246 }
29247 17 script_drawing_commands.Clear();
29248 //script_drawing_commands.push_commands(tmpDrawCommands);
29249 17 GameFlags &= ~GAMEFLAG_SCRIPTMENU_ACTIVE;
29250 48 }
29251 440 void FFScript::runOnLaunchEngine()
29252 {
29253
2/2
✓ Branch 0 taken 425 times.
✓ Branch 1 taken 15 times.
440 if(!globalscripts[GLOBAL_SCRIPT_ONLAUNCH]->valid()) return; //No script to run
29254 //Do NOT blit the prior screen to this bitmap; that would be the TITLE SCREEN.
29255 15 clear_to_color(script_menu_buf,BLACK);
29256 15 initZScriptGlobalScript(GLOBAL_SCRIPT_ONLAUNCH);
29257 15 GameFlags |= GAMEFLAG_SCRIPTMENU_ACTIVE;
29258 //auto tmpDrawCommands = script_drawing_commands.pop_commands();
29259
29260 15 auto& data = get_script_engine_data(ScriptType::Global, GLOBAL_SCRIPT_ONLAUNCH);
29261
4/4
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 15 times.
30 while (data.doscript && !Quit)
29262 {
29263 15 script_drawing_commands.Clear();
29264 15 load_control_state();
29265 15 ZScriptVersion::RunScript(ScriptType::Global, GLOBAL_SCRIPT_ONLAUNCH, GLOBAL_SCRIPT_ONLAUNCH);
29266
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 if (data.waitdraw)
29267 {
29268 ZScriptVersion::RunScript(ScriptType::Global, GLOBAL_SCRIPT_ONLAUNCH, GLOBAL_SCRIPT_ONLAUNCH);
29269 data.waitdraw = false;
29270 }
29271 //Draw
29272 15 clear_bitmap(framebuf);
29273
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if( !FFCore.system_suspend[susptCOMBOANIM] ) animate_combos();
29274
29275 15 doScriptMenuDraws();
29276 //
29277 15 advanceframe(true);
29278 }
29279 15 script_drawing_commands.Clear();
29280 //script_drawing_commands.push_commands(tmpDrawCommands);
29281 15 GameFlags &= ~GAMEFLAG_SCRIPTMENU_ACTIVE;
29282 440 }
29283 10 bool FFScript::runGenericFrozenEngine(const word script, const int32_t *init_data)
29284 {
29285 10 user_genscript& scr = user_genscript::get(script);
29286
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
10 if(script < 1 || script >= NUMSCRIPTSGENERIC) return false;
29287
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if(init_data)
29288 {
29289 for(int q = 0; q < 8; ++q)
29290 scr.initd[q] = init_data[q];
29291 }
29292
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if(!genericscripts[script]->valid()) return false; //No script to run
29293
29294
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(gen_frozen_index >= 400) // Experimentally tested to crash (stack overflow) at 500 for me -Em
29295 {
29296 Z_scripterrlog("Failed to run frozen generic script; too many (%zu) frozen scripts running already! Possible infinite recursion?\n", gen_frozen_index);
29297 return false;
29298 }
29299 //Store script refinfo
29300 10 push_ri();
29301 10 int local_i = int(gen_frozen_index++);
29302 10 reset_script_engine_data(ScriptType::GenericFrozen, local_i);
29303 //run script
29304 10 uint32_t fl = GameFlags & GAMEFLAG_SCRIPTMENU_ACTIVE;
29305 10 BITMAP* tmpbuf = script_menu_buf;
29306
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(fl)
29307 {
29308 script_menu_buf = create_bitmap_ex(8, framebuf->w, framebuf->h);
29309 }
29310 10 clear_bitmap(script_menu_buf);
29311 10 blit(framebuf, script_menu_buf, 0, 0, 0, 0, framebuf->w, framebuf->h);
29312 10 GameFlags |= GAMEFLAG_SCRIPTMENU_ACTIVE;
29313 //auto tmpDrawCommands = script_drawing_commands.pop_commands();
29314
4/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1542 times.
✓ Branch 2 taken 1542 times.
✓ Branch 3 taken 10 times.
1552 while(doscript(ScriptType::GenericFrozen, local_i) && !Quit)
29315 {
29316 1542 script_drawing_commands.Clear();
29317 1542 load_control_state();
29318 1542 ZScriptVersion::RunScript(ScriptType::GenericFrozen, script, local_i);
29319 //Draw
29320 1542 clear_bitmap(framebuf);
29321
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1542 times.
1542 if( !FFCore.system_suspend[susptCOMBOANIM] ) animate_combos();
29322 1542 doScriptMenuDraws();
29323 //
29324 1542 advanceframe(true);
29325 }
29326 10 script_drawing_commands.Clear();
29327 //script_drawing_commands.push_commands(tmpDrawCommands);
29328 //clear
29329 10 GameFlags &= ~GAMEFLAG_SCRIPTMENU_ACTIVE;
29330
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(fl)
29331 {
29332 GameFlags |= fl;
29333 destroy_bitmap(script_menu_buf);
29334 script_menu_buf = tmpbuf;
29335 }
29336 10 clear_script_engine_data(ScriptType::GenericFrozen, local_i);
29337 10 --gen_frozen_index;
29338 //Restore script refinfo
29339 10 pop_ri();
29340 10 return true;
29341 10 }
29342
29343 1480 bool FFScript::runScriptedActiveSubscreen()
29344 {
29345 1480 word activesubscript = DMaps[cur_dmap].active_sub_script;
29346
3/4
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 1439 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 41 times.
1480 if(!activesubscript || !dmapscripts[activesubscript]->valid()) return false; //No script to run
29347 41 word passivesubscript = DMaps[cur_dmap].passive_sub_script;
29348 41 word dmapactivescript = DMaps[cur_dmap].script;
29349 41 clear_bitmap(script_menu_buf);
29350 41 blit(framebuf, script_menu_buf, 0, 0, 0, 0, framebuf->w, framebuf->h);
29351 41 initZScriptScriptedActiveSubscreen();
29352 41 GameFlags |= GAMEFLAG_SCRIPTMENU_ACTIVE;
29353 41 word script_dmap = cur_dmap;
29354 //auto tmpDrawCommands = script_drawing_commands.pop_commands();
29355 41 pause_all_sfx();
29356 41 auto& data = get_script_engine_data(ScriptType::ScriptedActiveSubscreen);
29357
4/4
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 6772 times.
✓ Branch 2 taken 6772 times.
✓ Branch 3 taken 41 times.
6813 while (data.doscript && !Quit)
29358 {
29359 6772 script_drawing_commands.Clear();
29360 6772 load_control_state();
29361
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 6772 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
6772 if(get_qr(qr_DMAP_ACTIVE_RUNS_DURING_ACTIVE_SUBSCRIPT) && DMaps[script_dmap].script != 0 && doscript(ScriptType::DMap))
29362 {
29363 ZScriptVersion::RunScript(ScriptType::DMap, dmapactivescript, script_dmap);
29364 }
29365
4/6
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 6632 times.
✓ Branch 2 taken 140 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 140 times.
6772 if(get_qr(qr_PASSIVE_SUBSCRIPT_RUNS_DURING_ACTIVE_SUBSCRIPT)!=0 && DMaps[script_dmap].passive_sub_script != 0 && FFCore.doscript(ScriptType::ScriptedPassiveSubscreen))
29366 {
29367 140 ZScriptVersion::RunScript(ScriptType::ScriptedPassiveSubscreen, passivesubscript, script_dmap);
29368 140 }
29369 6772 ZScriptVersion::RunScript(ScriptType::ScriptedActiveSubscreen, activesubscript, script_dmap);
29370
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 6772 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
6772 if(waitdraw(ScriptType::DMap) && (get_qr(qr_DMAP_ACTIVE_RUNS_DURING_ACTIVE_SUBSCRIPT) && DMaps[script_dmap].script != 0 && doscript(ScriptType::DMap)))
29371 {
29372 ZScriptVersion::RunScript(ScriptType::DMap, dmapactivescript, script_dmap);
29373 waitdraw(ScriptType::DMap) = false;
29374 }
29375
5/8
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 6633 times.
✓ Branch 2 taken 139 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 139 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 139 times.
6772 if(waitdraw(ScriptType::ScriptedPassiveSubscreen) && (get_qr(qr_PASSIVE_SUBSCRIPT_RUNS_DURING_ACTIVE_SUBSCRIPT)!=0 && DMaps[script_dmap].passive_sub_script != 0 && FFCore.doscript(ScriptType::ScriptedPassiveSubscreen)))
29376 {
29377 139 ZScriptVersion::RunScript(ScriptType::ScriptedPassiveSubscreen, passivesubscript, script_dmap);
29378 139 waitdraw(ScriptType::ScriptedPassiveSubscreen) = false;
29379 139 }
29380
3/4
✓ Branch 0 taken 5472 times.
✓ Branch 1 taken 1300 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5472 times.
6772 if (data.waitdraw && data.doscript)
29381 {
29382 5472 ZScriptVersion::RunScript(ScriptType::ScriptedActiveSubscreen, activesubscript, script_dmap);
29383 5472 data.waitdraw = false;
29384 5472 }
29385 //Draw
29386 6772 clear_bitmap(framebuf);
29387
2/4
✓ Branch 0 taken 6772 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6772 times.
6772 if(cur_dmap == script_dmap && ( !FFCore.system_suspend[susptCOMBOANIM] ) ) animate_combos();
29388 6772 doScriptMenuDraws();
29389 //
29390 6772 advanceframe(true);
29391 //Handle warps; run game_loop once!
29392
1/2
✓ Branch 0 taken 6772 times.
✗ Branch 1 not taken.
6772 if(cur_dmap != script_dmap)
29393 {
29394 activesubscript = DMaps[cur_dmap].active_sub_script;
29395 if(!activesubscript || !dmapscripts[activesubscript]->valid()) return true; //No script to run
29396 passivesubscript = DMaps[cur_dmap].passive_sub_script;
29397 dmapactivescript = DMaps[cur_dmap].script;
29398 script_dmap = cur_dmap;
29399 //Reset the background image
29400 game_loop();
29401 clear_bitmap(script_menu_buf);
29402 blit(framebuf, script_menu_buf, 0, 0, 0, 0, framebuf->w, framebuf->h);
29403 //Now loop without advancing frame, so that the subscreen script can draw immediately.
29404 }
29405 }
29406 41 resume_all_sfx();
29407 41 script_drawing_commands.Clear();
29408 //script_drawing_commands.push_commands(tmpDrawCommands);
29409 41 GameFlags &= ~GAMEFLAG_SCRIPTMENU_ACTIVE;
29410 41 GameFlags |= GAMEFLAG_RESET_GAME_LOOP;
29411 41 return true;
29412 1480 }
29413 1119 bool FFScript::runOnMapScriptEngine()
29414 {
29415 1119 word onmap_script = DMaps[cur_dmap].onmap_script;
29416
3/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1112 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
1119 if(!onmap_script || !dmapscripts[onmap_script]->valid()) return false; //No script to run
29417 7 clear_bitmap(script_menu_buf);
29418 7 blit(framebuf, script_menu_buf, 0, 0, 0, 0, framebuf->w, framebuf->h);
29419 7 initZScriptOnMapScript();
29420 7 GameFlags |= GAMEFLAG_SCRIPTMENU_ACTIVE;
29421 7 word script_dmap = cur_dmap;
29422 //auto tmpDrawCommands = script_drawing_commands.pop_commands();
29423 7 pause_all_sfx();
29424
29425 7 auto& data = get_script_engine_data(ScriptType::OnMap);
29426
4/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 909 times.
✓ Branch 2 taken 909 times.
✓ Branch 3 taken 7 times.
916 while (data.doscript && !Quit)
29427 {
29428 909 script_drawing_commands.Clear();
29429 909 load_control_state();
29430 909 ZScriptVersion::RunScript(ScriptType::OnMap, onmap_script, script_dmap);
29431
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 909 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
909 if (data.waitdraw && data.doscript)
29432 {
29433 ZScriptVersion::RunScript(ScriptType::OnMap, onmap_script, script_dmap);
29434 data.waitdraw = false;
29435 }
29436 //Draw
29437 909 clear_bitmap(framebuf);
29438
2/4
✓ Branch 0 taken 909 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 909 times.
909 if(cur_dmap == script_dmap && ( !FFCore.system_suspend[susptCOMBOANIM] ) ) animate_combos();
29439 909 doScriptMenuDraws();
29440 //
29441 909 advanceframe(true);
29442 //Handle warps; run game_loop once!
29443
1/2
✓ Branch 0 taken 909 times.
✗ Branch 1 not taken.
909 if(cur_dmap != script_dmap)
29444 {
29445 onmap_script = DMaps[cur_dmap].onmap_script;
29446 if(!onmap_script || !dmapscripts[onmap_script]->valid()) return true; //No script to run
29447 script_dmap = cur_dmap;
29448 //Reset the background image
29449 game_loop();
29450 clear_bitmap(script_menu_buf);
29451 blit(framebuf, script_menu_buf, 0, 0, 0, 0, framebuf->w, framebuf->h);
29452 //Now loop without advancing frame, so that the subscreen script can draw immediately.
29453 }
29454 }
29455 7 resume_all_sfx();
29456 7 script_drawing_commands.Clear();
29457 //script_drawing_commands.push_commands(tmpDrawCommands);
29458 7 GameFlags &= ~GAMEFLAG_SCRIPTMENU_ACTIVE;
29459 7 GameFlags |= GAMEFLAG_RESET_GAME_LOOP;
29460 7 return true;
29461 1119 }
29462
29463 10068 void FFScript::doScriptMenuDraws()
29464 {
29465
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 10056 times.
10068 BITMAP* menu_buf = ((GameFlags & GAMEFLAG_F6SCRIPT_ACTIVE) != 0) ? f6_menu_buf : script_menu_buf;
29466 10068 blit(menu_buf, framebuf, 0, 0, 0, 0, framebuf->w, framebuf->h);
29467 //Script draws
29468 10068 do_script_draws(framebuf, origin_scr, 0, playing_field_offset);
29469 10068 }
29470
29471 277 void FFScript::runOnSaveEngine()
29472 {
29473
2/2
✓ Branch 0 taken 270 times.
✓ Branch 1 taken 7 times.
277 if(globalscripts[GLOBAL_SCRIPT_ONSAVE]->valid())
29474 {
29475 7 push_ri();
29476 //Prevent getting here via Quit from causing a forced-script-quit after 1000 commands!
29477 7 int32_t tQuit = Quit;
29478 7 Quit = 0;
29479 //
29480 7 initZScriptGlobalScript(GLOBAL_SCRIPT_ONSAVE);
29481 7 ZScriptVersion::RunScript(ScriptType::Global, GLOBAL_SCRIPT_ONSAVE, GLOBAL_SCRIPT_ONSAVE);
29482 //
29483 7 pop_ri();
29484 7 Quit = tQuit;
29485 7 }
29486 277 }
29487
29488 16550788 bool FFScript::itemScriptEngine()
29489 {
29490
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16550788 times.
16550788 if ( FFCore.system_suspend[susptITEMSCRIPTENGINE] ) return false;
29491
2/2
✓ Branch 0 taken 4237001728 times.
✓ Branch 1 taken 16550788 times.
4253552516 for ( int32_t q = 0; q < MAXITEMS; q++ )
29492 {
29493
29494
3/4
✓ Branch 0 taken 31422766 times.
✓ Branch 1 taken 4205578962 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 31422766 times.
4237001728 if ( itemsbuf[q].script <= 0 || itemsbuf[q].script > NUMSCRIPTITEM ) continue; // > NUMSCRIPTITEM as someone could force an invaid script slot!
29495
29496 31422766 auto& data = get_script_engine_data(ScriptType::Item, q);
29497
2/2
✓ Branch 0 taken 14167 times.
✓ Branch 1 taken 31408599 times.
31422766 if ( data.doscript < 1 ) continue;
29498
29499 //Passive items
29500
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14167 times.
14167 if (((itemsbuf[q].flags&item_passive_script)))
29501 {
29502 if(game->item[q] && (get_qr(qr_ITEMSCRIPTSKEEPRUNNING)))
29503 {
29504 if(get_qr(qr_PASSIVE_ITEM_SCRIPT_ONLY_HIGHEST)
29505 && current_item(itemsbuf[q].type) > itemsbuf[q].level)
29506 data.doscript = 0;
29507 else ZScriptVersion::RunScript(ScriptType::Item, itemsbuf[q].script, q&0xFFF);
29508 if(!data.doscript) //Item script ended. Clear the data, if any remains.
29509 {
29510 data.clear_ref();
29511 data.waitdraw = false;
29512 FFScript::deallocateAllScriptOwned(ScriptType::Item, q);
29513 }
29514 }
29515 }
29516 else
29517 {
29518
29519 //Normal Items
29520 /*! What happens here: When an item script is first run by the user using that utem, the script runs for one frame.
29521 After executing RunScript(), item_doscript is set to '1' in hero.cpp.
29522 If the quest allows the item to continue running, the itemScriptEngine() function ignores running the
29523 same item script (again) that frame, and insteads increments item_doscript to '2'.
29524 If item_doscript == 2, then we know we are on the second frame, and we run it perpetually.
29525 If the QR to enable item scripts to run for more than one frame is not enabled, then item_doscript is set to '0'.
29526 If the item flag 'PERPETUAL SCRIPT' is enabled, then we ignore the lack of item_doscript==2.
29527 This allows passive item scripts to function.
29528 */
29529
29530 14167 auto& data = get_script_engine_data(ScriptType::Item, q);
29531
29532
2/2
✓ Branch 0 taken 662 times.
✓ Branch 1 taken 13505 times.
14167 if ( data.doscript == 1 ) // FIrst frame, normally set in hero.cpp
29533 {
29534
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 662 times.
662 if ( get_qr(qr_ITEMSCRIPTSKEEPRUNNING) )
29535 {
29536 662 data.doscript = 2;
29537 662 }
29538 662 }
29539
1/2
✓ Branch 0 taken 13505 times.
✗ Branch 1 not taken.
13505 else if (data.doscript == 2) //Second frame and later, if scripts continue to run.
29540 {
29541 13505 ZScriptVersion::RunScript(ScriptType::Item, itemsbuf[q].script, q&0xFFF);
29542 13505 }
29543 else if (data.doscript == 3) //Run via itemdata->RunScript
29544 {
29545 if ( (get_qr(qr_ITEMSCRIPTSKEEPRUNNING)) )
29546 {
29547 data.doscript = 2; //Reduce to normal run status
29548 }
29549 else
29550 {
29551 ZScriptVersion::RunScript(ScriptType::Item, itemsbuf[q].script, q & 0xFFF);
29552 data.doscript = 0;
29553 }
29554 }
29555 else if(data.doscript==4) //Item set itself false, kill script and clear data here
29556 {
29557 data.doscript = 0;
29558 }
29559
2/2
✓ Branch 0 taken 13490 times.
✓ Branch 1 taken 677 times.
14167 if(data.doscript==0) //Item script ended. Clear the data, if any remains.
29560 {
29561 677 data.clear_ref();
29562 677 data.waitdraw = false;
29563 677 FFScript::deallocateAllScriptOwned(ScriptType::Item, q);
29564 677 }
29565 }
29566 14167 }
29567 16550788 return false;
29568 16550788 }
29569
29570 17092321 bool FFScript::itemScriptEngineOnWaitdraw()
29571 {
29572
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17092321 times.
17092321 if ( FFCore.system_suspend[susptITEMSCRIPTENGINE] ) return false;
29573
2/2
✓ Branch 0 taken 4375634176 times.
✓ Branch 1 taken 17092321 times.
4392726497 for ( int32_t q = 0; q < MAXITEMS; q++ )
29574 {
29575
3/4
✓ Branch 0 taken 33430535 times.
✓ Branch 1 taken 4342203641 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 33430535 times.
4375634176 if ( itemsbuf[q].script <= 0 || itemsbuf[q].script > NUMSCRIPTITEM ) continue; // > NUMSCRIPTITEM as someone could force an invaid script slot!
29576
29577 33430535 auto& data = get_script_engine_data(ScriptType::Item, q);
29578
29579
2/2
✓ Branch 0 taken 13491 times.
✓ Branch 1 taken 33417044 times.
33430535 if ( data.doscript < 1 ) continue;
29580
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13491 times.
13491 if (!data.waitdraw) continue;
29581 else data.waitdraw = false;
29582
29583 /*! What happens here: When an item script is first run by the user using that utem, the script runs for one frame.
29584 After executing RunScript(), item_doscript is set to '1' in hero.cpp.
29585 If the quest allows the item to continue running, the itemScriptEngine() function ignores running the
29586 same item script (again) that frame, and insteads increments item_doscript to '2'.
29587 If item_doscript == 2, then we know we are on the second frame, and we run it perpetually.
29588 If the QR to enable item scripts to run for more than one frame is not enabled, then item_doscript is set to '0'.
29589 If the item flag 'PERPETUAL SCRIPT' is enabled, then we ignore the lack of item_doscript==2.
29590 This allows passive item scripts to function.
29591 */
29592 //Passive items
29593 if ((itemsbuf[q].flags&item_passive_script))
29594 {
29595 if(game->item[q] && (get_qr(qr_ITEMSCRIPTSKEEPRUNNING)))
29596 {
29597 if(get_qr(qr_PASSIVE_ITEM_SCRIPT_ONLY_HIGHEST)
29598 && current_item(itemsbuf[q].type) > itemsbuf[q].level)
29599 data.doscript = 0;
29600 else ZScriptVersion::RunScript(ScriptType::Item, itemsbuf[q].script, q&0xFFF);
29601 if(!data.doscript) //Item script ended. Clear the data, if any remains.
29602 {
29603 data.clear_ref();
29604 data.waitdraw = false;
29605 FFScript::deallocateAllScriptOwned(ScriptType::Item, q);
29606 }
29607 }
29608 }
29609 else
29610 {
29611 //Normal items
29612 if ( data.doscript == 1 ) // FIrst frame, normally set in hero.cpp
29613 {
29614 if ( get_qr(qr_ITEMSCRIPTSKEEPRUNNING) )
29615 {
29616 data.doscript = 2;
29617 }
29618 else data.doscript = 0;
29619 }
29620 else if (data.doscript == 2) //Second frame and later, if scripts continue to run.
29621 {
29622 ZScriptVersion::RunScript(ScriptType::Item, itemsbuf[q].script, q&0xFFF);
29623 }
29624 else if (data.doscript == 3) //Run via itemdata->RunScript
29625 {
29626 if ( (get_qr(qr_ITEMSCRIPTSKEEPRUNNING)) )
29627 {
29628 data.doscript = 2; //Reduce to normal run status
29629 }
29630 else
29631 {
29632 ZScriptVersion::RunScript(ScriptType::Item, itemsbuf[q].script, q & 0xFFF);
29633 data.doscript = 0;
29634 }
29635 }
29636 else if(data.doscript==4) //Item set itself false, kill script and clear data here.
29637 {
29638 data.doscript = 0;
29639 }
29640 if(!data.doscript) //Item script ended. Clear the data, if any remains.
29641 {
29642 data.clear_ref();
29643 data.waitdraw = false;
29644 FFScript::deallocateAllScriptOwned(ScriptType::Item, q);
29645 }
29646 }
29647 }
29648 17092321 return false;
29649 17092321 }
29650 15347727 void FFScript::npcScriptEngineOnWaitdraw()
29651 {
29652
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15347727 times.
15347727 if ( FFCore.system_suspend[susptNPCSCRIPTS] ) return;
29653 15347727 guys.run_script(MODE_WAITDRAW);
29654 15347727 }
29655
29656 14834120 void FFScript::eweaponScriptEngine()
29657 {
29658
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14834120 times.
14834120 if ( FFCore.system_suspend[susptEWEAPONSCRIPTS] ) return;
29659 14834120 Ewpns.run_script(MODE_NORMAL);
29660 14834120 }
29661
29662 15347727 void FFScript::lweaponScriptEngineOnWaitdraw()
29663 {
29664
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15347727 times.
15347727 if ( FFCore.system_suspend[susptLWEAPONSCRIPTS] ) return;
29665 15347727 Lwpns.run_script(MODE_WAITDRAW);
29666 15347727 }
29667
29668 15377034 void FFScript::eweaponScriptEngineOnWaitdraw()
29669 {
29670
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 15377024 times.
15377034 if ( FFCore.system_suspend[susptEWEAPONSCRIPTS] ) return;
29671 15377024 Ewpns.run_script(MODE_WAITDRAW);
29672 15377034 }
29673
29674 14836746 void FFScript::itemSpriteScriptEngine()
29675 {
29676
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14836746 times.
14836746 if ( FFCore.system_suspend[susptITEMSPRITESCRIPTS] ) return;
29677 14836746 items.run_script(MODE_NORMAL);
29678 14836746 }
29679
29680 15379552 void FFScript::itemSpriteScriptEngineOnWaitdraw()
29681 {
29682
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15379552 times.
15379552 if ( FFCore.system_suspend[susptITEMSPRITESCRIPTS] ) return;
29683 15379552 items.run_script(MODE_WAITDRAW);
29684 15379552 }
29685
29686
29687 15 int32_t FFScript::getTime(int32_t type)
29688 {
29689 //struct tm *tm_struct = localtime(time(NULL));
29690 struct tm * tm_struct;
29691 time_t sysRTC;
29692 15 time (&sysRTC);
29693 15 tm_struct = localtime (&sysRTC);
29694 15 int32_t rval = -1;
29695
29696
5/10
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
15 switch(type)
29697 {
29698 case curyear:
29699 {
29700 //Year format starts at 1900, yeat
29701 //A raw read of '2018' would be '118', so we add 1900 to it to derive the actual year.
29702 3 rval = tm_struct->tm_year + 1900; break;
29703
29704 }
29705 case curmonth:
29706 {
29707 //Months start at 0, but we want 1->12
29708 rval = tm_struct->tm_mon +1; break;
29709 }
29710 case curday_month:
29711 {
29712 rval = tm_struct->tm_mday; break;
29713 }
29714 case curday_week:
29715 {
29716 //It seems that weekdays are a value range of 1 to 7.
29717 rval = tm_struct->tm_wday; break;
29718 }
29719 case curhour:
29720 {
29721 3 rval = tm_struct->tm_hour; break;
29722 }
29723 case curminute:
29724 {
29725 3 rval = tm_struct->tm_min; break;
29726 }
29727 case cursecond:
29728 {
29729 3 rval = tm_struct->tm_sec; break;
29730 }
29731 case curdayyear:
29732 {
29733 //The day (n/365) out of the entire year.
29734 3 rval = tm_struct->tm_yday; break;
29735 }
29736 case curDST:
29737 {
29738 //Returns if the user is in a Time Zone with Daylight TIme of some sort.
29739 //View the time.h docs for the actual values of this struct element.
29740 rval = tm_struct->tm_isdst;; break;
29741 }
29742 default:
29743 {
29744 al_trace("Invalid category passed to GetSystemTime(%d)\n",type);
29745 rval = -1; break;
29746 }
29747
29748 }
29749 15 return rval;
29750 }
29751
29752 2511 void FFScript::do_lweapon_delete()
29753 {
29754
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2511 times.
2511 if(auto s=checkLWpn(GET_REF(lwpnref)))
29755 {
29756
1/2
✓ Branch 0 taken 2511 times.
✗ Branch 1 not taken.
2511 if(s==Hero.lift_wpn)
29757 {
29758 delete s;
29759 Hero.lift_wpn = nullptr;
29760 }
29761 2511 else Lwpns.del(s);
29762 2511 }
29763 2511 }
29764
29765 1482 void FFScript::do_eweapon_delete()
29766 {
29767
1/2
✓ Branch 0 taken 1482 times.
✗ Branch 1 not taken.
1482 if(auto s=checkEWpn(GET_REF(ewpnref)))
29768 {
29769 1482 Ewpns.del(s);
29770 1482 }
29771 1482 }
29772
29773 void FFScript::updateIncludePaths()
29774 {
29775 // TODO: remove this from FFScript - must also remove ffscript.h being used in ./src/zq
29776 }
29777
29778 void FFScript::initIncludePaths()
29779 {
29780 // TODO: remove this from FFScript - must also remove ffscript.h being used in ./src/zq
29781 }
29782
29783 bool FFScript::checkExtension(std::string &filename, const std::string &extension)
29784 //inline bool checkExtension(std::string filename, std::string extension)
29785 {
29786 int32_t dot = filename.find_last_of(".");
29787 std::string exten = (dot == std::string::npos ? "" : filename.substr(dot, filename.length() - dot));
29788 return exten == extension;
29789 }
29790
29791 2544 void FFScript::do_strcmp()
29792 {
29793 2544 int32_t arrayptr_a = GET_D(rINDEX);
29794 2544 int32_t arrayptr_b = GET_D(rINDEX2);
29795 2544 string strA;
29796 2544 string strB;
29797
1/2
✓ Branch 0 taken 2544 times.
✗ Branch 1 not taken.
2544 ArrayH::getString(arrayptr_a, strA);
29798
1/2
✓ Branch 0 taken 2544 times.
✗ Branch 1 not taken.
2544 ArrayH::getString(arrayptr_b, strB);
29799
1/2
✓ Branch 0 taken 2544 times.
✗ Branch 1 not taken.
2544 set_register(sarg1, (strcmp(strA.c_str(), strB.c_str()) * 10000));
29800 2544 }
29801
29802 void FFScript::do_stricmp()
29803 {
29804 int32_t arrayptr_a = GET_D(rINDEX);
29805 int32_t arrayptr_b = GET_D(rINDEX2);
29806 string strA;
29807 string strB;
29808 ArrayH::getString(arrayptr_a, strA);
29809 ArrayH::getString(arrayptr_b, strB);
29810 set_register(sarg1, (stricmp(strA.c_str(), strB.c_str()) * 10000));
29811 }
29812
29813 2 void FFScript::do_LowerToUpper(const bool v)
29814 {
29815 2 int32_t arrayptr_a = get_register(sarg1);
29816 2 string strA;
29817
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 ArrayH::getString(arrayptr_a, strA);
29818
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
8 for (char& c : strA)
29819 6 c = std::toupper(c);
29820
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 ArrayH::setArray(arrayptr_a, strA);
29821
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 set_register(sarg1, 10000); // used to return 0 if string was empty.
29822 2 }
29823
29824 void FFScript::do_UpperToLower(const bool v)
29825 {
29826 int32_t arrayptr_a = get_register(sarg1);
29827 string strA;
29828 ArrayH::getString(arrayptr_a, strA);
29829 for (char& c : strA)
29830 c = std::tolower(c);
29831 ArrayH::setArray(arrayptr_a, strA);
29832 set_register(sarg1, 10000); // used to return 0 if string was empty.
29833 }
29834
29835 void FFScript::do_getnpcscript()
29836 {
29837 do_get_script_index_by_name(name_to_slot_index_npcmap);
29838 }
29839
29840 234 void FFScript::do_getcomboscript()
29841 {
29842 234 do_get_script_index_by_name(name_to_slot_index_comboscriptmap);
29843 234 }
29844
29845 137140 void FFScript::do_getgenericscript()
29846 {
29847 137140 do_get_script_index_by_name(name_to_slot_index_genericmap);
29848 137140 }
29849
29850 7914 void FFScript::do_getlweaponscript()
29851 {
29852 7914 do_get_script_index_by_name(name_to_slot_index_lwpnmap);
29853 7914 }
29854 4623 void FFScript::do_geteweaponscript()
29855 {
29856 4623 do_get_script_index_by_name(name_to_slot_index_ewpnmap);
29857 4623 }
29858 void FFScript::do_getheroscript()
29859 {
29860 do_get_script_index_by_name(name_to_slot_index_playermap);
29861 }
29862 void FFScript::do_getglobalscript()
29863 {
29864 do_get_script_index_by_name(name_to_slot_index_globalmap);
29865 }
29866 906 void FFScript::do_getdmapscript()
29867 {
29868 906 do_get_script_index_by_name(name_to_slot_index_dmapmap);
29869 906 }
29870 void FFScript::do_getscreenscript()
29871 {
29872 do_get_script_index_by_name(name_to_slot_index_screenmap);
29873 }
29874 115 void FFScript::do_getitemspritescript()
29875 {
29876 115 do_get_script_index_by_name(name_to_slot_index_itemspritemap);
29877 115 }
29878 //Not assigned to slots at present. If they ever are, then this would get the id of any script (any type) by name. -Z
29879 void FFScript::do_getuntypedscript()
29880 {
29881 set_register(sarg1, 0);
29882 }
29883 void FFScript::do_getsubscreenscript()
29884 {
29885 do_get_script_index_by_name(name_to_slot_index_subscreenmap);
29886 }
29887 void FFScript::do_getnpcbyname()
29888 {
29889 int32_t arrayptr = get_register(sarg1);
29890 string the_string;
29891 int32_t num = -1;
29892 ArrayH::getString(arrayptr, the_string, 256); //What is the max length of a script identifier?
29893
29894 for(int32_t q = 0; q < MAXNPCS; q++)
29895 {
29896 if(!(strcmp(the_string.c_str(), guy_string[q])))
29897 {
29898 num = q;
29899 break;
29900 }
29901 }
29902 set_register(sarg1, (num * 10000));
29903 }
29904 void FFScript::do_getitembyname()
29905 {
29906 int32_t arrayptr = get_register(sarg1);
29907 string the_string;
29908 int32_t num = -1;
29909 ArrayH::getString(arrayptr, the_string, 256); //What is the max length of a script identifier?
29910
29911 for(int32_t q = 0; q < MAXITEMS; q++)
29912 {
29913 if(!(strcmp(the_string.c_str(), item_string[q])))
29914 {
29915 num = q;
29916 break;
29917 }
29918 }
29919 set_register(sarg1, (num * 10000));
29920 }
29921 void FFScript::do_getcombobyname()
29922 {
29923 int32_t arrayptr = get_register(sarg1);
29924 string the_string;
29925 int32_t num = -1;
29926 ArrayH::getString(arrayptr, the_string, 256);
29927
29928 if (!the_string.empty())
29929 {
29930 for(int32_t q = 0; q < MAXCOMBOS; q++)
29931 {
29932 if (the_string == combobuf[q].label)
29933 {
29934 num = q;
29935 break;
29936 }
29937 }
29938 }
29939 set_register(sarg1, (num * 10000));
29940 }
29941 void FFScript::do_getdmapbyname()
29942 {
29943 int32_t arrayptr = get_register(sarg1);
29944 string the_string;
29945 int32_t num = -1;
29946 ArrayH::getString(arrayptr, the_string, 256); //What is the max length of a script identifier?
29947
29948 for(int32_t q = 0; q < MAXDMAPS; q++)
29949 {
29950 if(!(strcmp(the_string.c_str(), DMaps[q].name)))
29951 {
29952 num = q;
29953 break;
29954 }
29955 }
29956 set_register(sarg1, (num * 10000));
29957 }
29958
29959 ////////////////////////
29960 /// String Utilities ///
29961 ////////////////////////
29962 void FFScript::do_ConvertCase(const bool v)
29963 {
29964 int32_t arrayptr_a = get_register(sarg1);
29965 string strA;
29966 ArrayH::getString(arrayptr_a, strA);
29967 for (char& c : strA)
29968 {
29969 if (c < 'a')
29970 c += 32 * (c >= 'A' && c <= 'Z');
29971 else
29972 c -= 32 * (c >= 'a' && c <= 'z');
29973 }
29974 ArrayH::setArray(arrayptr_a, strA);
29975 set_register(sarg1, (10000)); // used to return 0 if string was empty.
29976 }
29977
29978 void FFScript::do_xlen(const bool v)
29979 {
29980 //not implemented, xlen not found
29981 int32_t arrayptr = (SH::get_arg(sarg2, v));
29982 string str;
29983 ArrayH::getString(arrayptr, str);
29984 }
29985
29986 void FFScript::do_xtoi(const bool v)
29987 {
29988 int32_t arrayptr = (SH::get_arg(sarg2, v));
29989 string str;
29990 ArrayH::getString(arrayptr, str);
29991 double val = zc_xtoi(const_cast<char*>(str.c_str()));
29992 set_register(sarg1, (int32_t)(val) * 10000);
29993 }
29994 void FFScript::do_xtoi2()
29995 {
29996 int32_t arrayptr_a = GET_D(rINDEX);
29997 string strA;
29998 ArrayH::getString(arrayptr_a, strA);
29999 set_register(sarg1, (zc_xtoi(strA.c_str()) * 10000));
30000 }
30001
30002 // Calculates log2 of number.
30003 double FFScript::Log2( double n )
30004 {
30005 // log(n)/log(2) is log2.
30006 return log( (double)n ) / log( (double)2 );
30007 }
30008
30009 //xtoa, convert hex number to hex ascii
30010 14 void FFScript::do_xtoa()
30011 {
30012
30013 14 int32_t arrayptr_a = get_register(sarg1);
30014 14 int32_t number = get_register(sarg2) / 10000;//GET_D(rEXP2)/10000; //why are you not in sarg2?!!
30015
30016
30017
30018 14 bool isneg = false;
30019
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 if ( number < 0 )
30020 {
30021 isneg = true;
30022 number *= -1;
30023 }
30024 14 double num = number;
30025
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 int32_t digits = num ? floor(FFCore.LogToBase(num, 16) + 1) : 1;
30026
30027
30028 14 int32_t pos = 0;
30029 14 string strA;
30030
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if(number == 0) //Needs to precede str.resize(digits+3) as if the number is <= 0 then this breaks.
30031 {
30032 strA.resize(3);
30033 strA[pos+2] = '0';
30034 if(ArrayH::setArray(arrayptr_a, strA) == SH::_Overflow)
30035 {
30036 Z_scripterrlog("Dest string supplied to 'itoa()' not large enough\n");
30037 set_register(sarg1, 0);
30038 }
30039 else set_register(sarg1, 30000); //returns the pointer to the dest
30040 return;
30041 }
30042 14 int32_t ret = 0;
30043
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 strA.resize(digits+3+(isneg?1:0));
30044 //num = Floor(Abs(num));
30045
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if ( isneg )
30046 {
30047 strA[pos] = '-';
30048 strA[pos+1] = '0';
30049 strA[pos+2] = 'x';
30050 ret = 3;
30051 }
30052 else
30053 {
30054
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 strA[pos] = '0';
30055
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 strA[pos+1] = 'x';
30056 14 ret = 2;
30057 }
30058
30059 14 int32_t alphaoffset = 'A' - 0xA;
30060
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 24 times.
38 for(int32_t i = 0; i < digits; ++i)
30061 {
30062
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 int32_t coeff = ((int32_t)floor((double)(((double)number) / pow((float)0x10, digits - i - 1))) % 0x10);
30063
3/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
24 strA[pos + ret + i] = coeff < 0xA ? coeff + '0' : coeff + alphaoffset;
30064 24 }
30065
2/4
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
14 if(ArrayH::setArray(arrayptr_a, strA) == SH::_Overflow)
30066 {
30067 scripting_log_error_with_context("Dest string parameter not large enough");
30068 set_register(sarg1, 0);
30069 }
30070
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 else set_register(sarg1, (ret + digits -(isneg?1:0))*10000); //don't count the - sign as a digit
30071
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 }
30072
30073 void FFScript::do_ilen(const bool v)
30074 {
30075 int32_t arrayptr = (SH::get_arg(sarg2, v));
30076 string str;
30077 ArrayH::getString(arrayptr, str);
30078 set_register(sarg1, (FFCore.ilen((char*)str.c_str()) * 10000));
30079 }
30080
30081 //! Note atoi2 (atoi(str, len) can be accompished with str.resize after getString.
30082 void FFScript::do_atoi(const bool v)
30083 {
30084 int32_t arrayptr = (SH::get_arg(sarg2, v));
30085 string str;
30086 ArrayH::getString(arrayptr, str);
30087 set_register(sarg1, (atoi(str.c_str()) * 10000));
30088 }
30089 void FFScript::do_atol(const bool v)
30090 {
30091 int32_t arrayptr = (SH::get_arg(sarg2, v));
30092 string str;
30093 ArrayH::getString(arrayptr, str);
30094 set_register(sarg1, (atoi(str.c_str())));
30095 }
30096
30097 void FFScript::do_strstr()
30098 {
30099
30100 int32_t arrayptr_a = GET_D(rINDEX);
30101 int32_t arrayptr_b = GET_D(rINDEX2);
30102 string strA;
30103 string strB;
30104 ArrayH::getString(arrayptr_a, strA);
30105 ArrayH::getString(arrayptr_b, strB);
30106 if ( strA.size() < 1 )
30107 {
30108 scripting_log_error_with_context("String parameter is too small. Size is: {}", strA.size());
30109 set_register(sarg1,-10000);
30110 return;
30111 }
30112 set_register(sarg1, (strA.find(strB) * 10000));
30113 }
30114
30115 935 void FFScript::do_strcat()
30116 {
30117
30118 935 int32_t arrayptr_a = GET_D(rINDEX);
30119 935 int32_t arrayptr_b = GET_D(rINDEX2);
30120 935 string strA;
30121 935 string strB;
30122
1/2
✓ Branch 0 taken 935 times.
✗ Branch 1 not taken.
935 ArrayH::getString(arrayptr_a, strA);
30123
1/2
✓ Branch 0 taken 935 times.
✗ Branch 1 not taken.
935 ArrayH::getString(arrayptr_b, strB);
30124 //char str_c[2048];
30125 //strcpy(str_c, strA.c_str());
30126
1/2
✓ Branch 0 taken 935 times.
✗ Branch 1 not taken.
935 string strC = strA + strB;
30127
2/4
✓ Branch 0 taken 935 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 935 times.
935 if(ArrayH::setArray(arrayptr_a, strC) == SH::_Overflow)
30128 {
30129 scripting_log_error_with_context("Dest string parameter is too small. Size is: {}", strA.size());
30130 set_register(sarg1, 0);
30131 }
30132
1/2
✓ Branch 0 taken 935 times.
✗ Branch 1 not taken.
935 else set_register(sarg1, arrayptr_a); //returns the pointer to the dest
30133 935 }
30134 void FFScript::do_strspn()
30135 {
30136
30137 int32_t arrayptr_a = GET_D(rINDEX);
30138 int32_t arrayptr_b = GET_D(rINDEX2);
30139 string strA;
30140 string strB;
30141 ArrayH::getString(arrayptr_a, strA);
30142 ArrayH::getString(arrayptr_b, strB);
30143 set_register(sarg1, (strspn(strA.c_str(), strB.c_str()) * 10000));
30144 }
30145
30146 void FFScript::do_strcspn()
30147 {
30148
30149 int32_t arrayptr_a = GET_D(rINDEX);
30150 int32_t arrayptr_b = GET_D(rINDEX2);
30151 string strA;
30152 string strB;
30153 ArrayH::getString(arrayptr_a, strA);
30154 ArrayH::getString(arrayptr_b, strB);
30155 set_register(sarg1, (strcspn(strA.c_str(), strB.c_str()) * 10000));
30156 }
30157
30158 void FFScript::do_strchr()
30159 {
30160
30161 int32_t arrayptr_a = GET_D(rINDEX);
30162 char chr_to_find = (GET_D(rINDEX2)/10000);
30163 string strA;
30164 ArrayH::getString(arrayptr_a, strA);
30165 if ( strA.size() < 1 )
30166 {
30167 scripting_log_error_with_context("String parameter is too small. Size is: {}", strA.size());
30168 set_register(sarg1,-10000);
30169 return;
30170 }
30171
30172 set_register(sarg1,strA.find_first_of(chr_to_find)*10000);
30173 }
30174 void FFScript::do_strrchr()
30175 {
30176 int32_t arrayptr_a = GET_D(rINDEX);
30177 char chr_to_find = (GET_D(rINDEX2)/10000);
30178 string strA;
30179 ArrayH::getString(arrayptr_a, strA);
30180 if ( strA.size() < 1 )
30181 {
30182 scripting_log_error_with_context("String parameter is too small. Size is: {}", strA.size());
30183 set_register(sarg1,-10000);
30184 return;
30185 }
30186 set_register(sarg1,strA.find_last_of(chr_to_find)*10000);
30187 }
30188
30189 void FFScript::do_remchr2()
30190 {
30191 //Not implemented, remchr not found
30192 //not part of any standard library
30193 int32_t arrayptr_a = GET_D(rINDEX);
30194 string strA;
30195 ArrayH::getString(arrayptr_a, strA);
30196 }
30197 //Bookmark
30198 void FFScript::do_atoi2()
30199 {
30200 //not implemented; atoi does not take 2 params
30201 int32_t arrayptr_a = GET_D(rINDEX);
30202 string strA;
30203 ArrayH::getString(arrayptr_a, strA);
30204 }
30205 void FFScript::do_ilen2()
30206 {
30207 //not implemented, ilen not found
30208 int32_t arrayptr_a = GET_D(rINDEX);
30209 string strA;
30210 ArrayH::getString(arrayptr_a, strA);
30211 }
30212 void FFScript::do_xlen2()
30213 {
30214 //not implemented, xlen not found
30215 int32_t arrayptr_a = GET_D(rINDEX);
30216 string strA;
30217 ArrayH::getString(arrayptr_a, strA);
30218 }
30219
30220 4797 void FFScript::do_itoa()
30221 {
30222 4797 int32_t arrayptr_a = get_register(sarg1);
30223 4797 int32_t number = get_register(sarg2) / 10000;
30224
30225 char buf[16];
30226 4797 zc_itoa(number, buf, 10);
30227 4797 int32_t ret = ::strlen(buf) * 10000L;
30228
1/2
✓ Branch 0 taken 4797 times.
✗ Branch 1 not taken.
4797 string strA(buf);
30229
30230
2/4
✓ Branch 0 taken 4797 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4797 times.
4797 if(ArrayH::setArray(arrayptr_a, strA) == SH::_Overflow)
30231 {
30232 scripting_log_error_with_context("Dest string parameter is too small. Size is: {}", strA.size());
30233 set_register(sarg1, -1);
30234 }
30235
1/2
✓ Branch 0 taken 4797 times.
✗ Branch 1 not taken.
4797 else set_register(sarg1, ret); //returns the number of digits used
30236 4797 }
30237
30238 56 void FFScript::do_itoacat()
30239 {
30240 56 int32_t arrayptr_a = get_register(sarg1);
30241 56 int32_t number = get_register(sarg2) / 10000;
30242
30243 56 double num = number;
30244 56 int32_t digits = FFCore.numDigits(number); //int32_t(log10(temp) * 10000.0)
30245 56 int32_t pos = 0;
30246 56 int32_t ret = 0;
30247 56 string strA;
30248 56 string strB;
30249
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 strB.resize(digits);
30250
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 ArrayH::getString(arrayptr_a, strA);
30251
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 if(num < 0)
30252 {
30253 strB.resize(digits+1);
30254 strB[pos] = '-';
30255 ++ret;
30256 num = -num;
30257 }
30258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 else if(num == 0)
30259 {
30260 strB[pos] = '0';
30261 string strC = strA + strB;
30262 if(ArrayH::setArray(arrayptr_a, strC) == SH::_Overflow)
30263 {
30264 scripting_log_error_with_context("Dest string parameter is too small. Size is: {}", strA.size());
30265 set_register(sarg1, 0);
30266 }
30267 else set_register(sarg1, arrayptr_a); //returns the pointer to the dest
30268 return;
30269 }
30270
30271
30272
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 84 times.
140 for(int32_t i = 0; i < digits; ++i)
30273
2/4
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 84 times.
✗ Branch 3 not taken.
84 strB[pos + ret + i] = ((int32_t)floor((double)(num / pow((float)10, digits - i - 1))) % 10) + '0';
30274
30275
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 string strC = strA + strB;
30276
2/4
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 56 times.
56 if(ArrayH::setArray(arrayptr_a, strC) == SH::_Overflow)
30277 {
30278 scripting_log_error_with_context("Dest string parameter is too small. Size is: {}", strA.size());
30279 set_register(sarg1, 0);
30280 }
30281
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 else set_register(sarg1, arrayptr_a); //returns the pointer to the dest
30282
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 }
30283
30284 14127 void FFScript::do_strcpy(const bool a, const bool b)
30285 {
30286 14127 int32_t arrayptr_b = SH::get_arg(sarg1, a);
30287 14127 int32_t arrayptr_a = SH::get_arg(sarg2, b);
30288
30289 14127 string strA;
30290
30291
1/2
✓ Branch 0 taken 14127 times.
✗ Branch 1 not taken.
14127 ArrayH::getString(arrayptr_a, strA);
30292
30293
2/4
✓ Branch 0 taken 14127 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14127 times.
14127 if(ArrayH::setArray(arrayptr_b, strA) == SH::_Overflow)
30294 scripting_log_error_with_context("Dest string parameter is too small. Size is: {}", strA.size());
30295 14127 }
30296 2 void FFScript::do_arraycpy(const bool a, const bool b)
30297 {
30298 2 int32_t arrayptr_dest = SH::get_arg(sarg1, a);
30299 2 int32_t arrayptr_src = SH::get_arg(sarg2, b);
30300 2 ArrayH::copyValues(arrayptr_dest, arrayptr_src);
30301 2 }
30302 17252 void FFScript::do_strlen(const bool v)
30303 {
30304 17252 int32_t arrayptr = (SH::get_arg(sarg2, v));
30305 17252 string str;
30306
1/2
✓ Branch 0 taken 17252 times.
✗ Branch 1 not taken.
17252 ArrayH::getString(arrayptr, str);
30307
1/2
✓ Branch 0 taken 17252 times.
✗ Branch 1 not taken.
17252 set_register(sarg1, (str.length() * 10000));
30308 17252 }
30309
30310 void FFScript::do_strncmp()
30311 {
30312 int32_t arrayptr_a = GET_D(rINDEX);
30313 int32_t arrayptr_b = GET_D(rEXP2);
30314 int32_t len = GET_D(rEXP1)/10000;
30315 string strA;
30316 string strB;
30317 ArrayH::getString(arrayptr_a, strA);
30318 ArrayH::getString(arrayptr_b, strB);
30319 set_register(sarg1, (strncmp(strA.c_str(), strB.c_str(), len) * 10000));
30320 }
30321
30322 void FFScript::do_strnicmp()
30323 {
30324 int32_t arrayptr_a = GET_D(rINDEX);
30325 int32_t arrayptr_b = GET_D(rEXP2);
30326 int32_t len = GET_D(rEXP1)/10000;
30327 string strA;
30328 string strB;
30329 ArrayH::getString(arrayptr_a, strA);
30330 ArrayH::getString(arrayptr_b, strB);
30331 set_register(sarg1, (ustrnicmp(strA.c_str(), strB.c_str(), len) * 10000));
30332 }
30333
30334 /////////////////////
30335 /// MATHS HELPERS ///
30336 /////////////////////
30337
30338 //Returns the log of val to the base 10. Any value <= 0 will return 0.
30339 int32_t FFScript::Log10(double temp)
30340 {
30341 int32_t ret = 0;
30342 if(temp > 0)
30343 ret = int32_t(log10(temp) * 10000.0);
30344 else ret = 0;
30345 return ret;
30346 }
30347
30348 //Returns the number of digits in a given integer.
30349 56 int32_t FFScript::numDigits(int32_t number)
30350 {
30351 56 int32_t digits = 0;
30352
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 56 times.
140 while (number)
30353 {
30354 84 number /= 10;
30355 84 digits++;
30356 }
30357 56 return digits;
30358 }
30359
30360 // Returns the natural logarithm of val (to the base e). Any value <= 0 will return 0.
30361 28 double FFScript::ln(double temp)
30362 {
30363
30364
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 if(temp > 0)
30365 28 return (log(temp));
30366 else
30367 {
30368 return 0;
30369 }
30370 28 }
30371
30372 // Returns the logarithm of x to the given base.
30373 14 double FFScript::LogToBase(double x, double base)
30374 {
30375
2/4
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
14 if(x <= 0 || base <= 0) return 0;
30376 14 return FFCore.ln(x)/FFCore.ln(base);
30377 14 }
30378
30379 ///----------------------------------------------------------------------------------------------------//
30380 //Debugger and Logging Consoles
30381
30382 template <typename ...Params>
30383 void FFScript::ZScriptConsole(int32_t attributes,const char *format, Params&&... params)
30384 {
30385 //if ( open )
30386 {
30387 zscript_coloured_console.Create("ZQuest Classic Logging Console", 600, 200, NULL, NULL);
30388 zscript_coloured_console.cls(CConsoleLoggerEx::COLOR_BACKGROUND_BLACK);
30389 zscript_coloured_console.gotoxy(0,0);
30390 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_BLUE | CConsoleLoggerEx::COLOR_INTENSITY |
30391 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK,"ZQuest Classic Logging Console\n");
30392
30393 zscript_coloured_console.cprintf( attributes, format, std::forward<Params>(params)...);
30394 }
30395 //else
30396 //{
30397 //close
30398 // zscript_coloured_console.Close();
30399 //}
30400 }
30401
30402 443 void clearConsole()
30403 {
30404 443 zscript_coloured_console.cls(CConsoleLoggerEx::COLOR_BACKGROUND_BLACK);
30405 443 zscript_coloured_console.gotoxy(0,0);
30406
30407 443 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_RED | CConsoleLoggerEx::COLOR_BLUE | CConsoleLoggerEx::COLOR_INTENSITY |
30408 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK,"\n _____ ____ __ \n");
30409 443 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_RED | CConsoleLoggerEx::COLOR_BLUE | CConsoleLoggerEx::COLOR_INTENSITY |
30410 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK," /__ / / __ \\__ _____ _____/ /_\n");
30411 443 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_RED | CConsoleLoggerEx::COLOR_BLUE | CConsoleLoggerEx::COLOR_INTENSITY |
30412 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK," / / / / / / / / / _ \\/ ___/ __/\n");
30413 443 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_RED | CConsoleLoggerEx::COLOR_BLUE | CConsoleLoggerEx::COLOR_INTENSITY |
30414 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK," / /__/ /_/ / /_/ / __(__ ) /_ \n");
30415 443 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_RED | CConsoleLoggerEx::COLOR_BLUE | CConsoleLoggerEx::COLOR_INTENSITY |
30416 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK," /____/\\___\\_\\__,_/\\___/____/\\__/\n\n");
30417
30418 443 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_BLUE | CConsoleLoggerEx::COLOR_INTENSITY |
30419 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK,"ZC Console\n");
30420
30421 886 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_BLUE |CConsoleLoggerEx::COLOR_GREEN | CConsoleLoggerEx::COLOR_INTENSITY |
30422 443 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK,"Running: %s\n", getVersionString());
30423
2/2
✓ Branch 0 taken 327 times.
✓ Branch 1 taken 116 times.
443 if ( FFCore.getQuestHeaderInfo(vZelda) > 0 )
30424 {
30425 116 char const* verstr = QHeader.getVerStr();
30426
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 116 times.
116 if(verstr[0])
30427 {
30428 116 auto vercmp = QHeader.compareVer();
30429 116 auto astatecmp = compare(int32_t(QHeader.getAlphaState()), getAlphaState());
30430 116 auto avercmp = compare(QHeader.getAlphaVer(), 0);
30431 116 auto timecmp = QHeader.compareDate();
30432
4/6
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 93 times.
✓ Branch 2 taken 23 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 23 times.
116 if(!(vercmp || astatecmp || avercmp))
30433 {
30434
3/4
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
23 if(!timecmp || !QHeader.new_version_is_nightly)
30435 46 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_BLUE |CConsoleLoggerEx::COLOR_GREEN | CConsoleLoggerEx::COLOR_INTENSITY |
30436 23 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK,"Quest Made in this build\n", verstr);
30437 else if(timecmp < 0)
30438 {
30439 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_BLUE |CConsoleLoggerEx::COLOR_GREEN | CConsoleLoggerEx::COLOR_INTENSITY |
30440 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK,"Quest Made in an earlier nightly of the same build\n", verstr);
30441 }
30442 else
30443 {
30444 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_BLUE |CConsoleLoggerEx::COLOR_GREEN | CConsoleLoggerEx::COLOR_INTENSITY |
30445 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK,"Quest Made in an LATER nightly of the same build!\n"
30446 "This may be unsafe to play in this version!\n", verstr);
30447 }
30448 23 }
30449 186 else zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_BLUE |CConsoleLoggerEx::COLOR_GREEN | CConsoleLoggerEx::COLOR_INTENSITY |
30450 93 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK,"Quest Made in: %s\n", verstr);
30451 116 }
30452 116 }
30453 443 }
30454 void FFScript::ZScriptConsole(bool open)
30455 {
30456 if ( open )
30457 {
30458 zscript_coloured_console.Create("ZC Console", 600, 200, NULL, NULL);
30459 clearConsole();
30460 console_enabled = 1;
30461 }
30462 else
30463 {
30464 zscript_coloured_console.Close();
30465 console_enabled = 0;
30466 }
30467 zc_set_config("CONSOLE","enabled",console_enabled);
30468 }
30469
30470 ///----------------------------------------------------------------------------------------------------//
30471 //Tracing
30472
30473 12567 void FFScript::do_trace(bool v)
30474 {
30475
5/14
✗ Branch 0 not taken.
✓ Branch 1 taken 12567 times.
✓ Branch 2 taken 12567 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12567 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 12567 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 12567 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
25134 bool should_replay_trace = replay_is_active() && replay_get_meta_bool("script_trace");
30476 // For now, only prevent tracing to allegro log for Web version. Some quests may expect players to
30477 // look in the logs for spoiler/secret stuff.
30478 #ifdef __EMSCRIPTEN__
30479 bool should_trace = console_enabled || should_replay_trace;
30480 if (!should_trace) return;
30481 #endif
30482
30483 12567 int32_t temp = SH::get_arg(sarg1, v);
30484
30485 char tmp[100];
30486
2/2
✓ Branch 0 taken 12561 times.
✓ Branch 1 taken 6 times.
12567 sprintf(tmp, (temp < 0 ? "%06d" : "%05d"), temp);
30487
1/2
✓ Branch 0 taken 12567 times.
✗ Branch 1 not taken.
12567 string s2(tmp);
30488
5/10
✓ Branch 0 taken 12567 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12567 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12567 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 12567 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 12567 times.
✗ Branch 9 not taken.
12567 s2 = s2.substr(0, s2.size() - 4) + "." + s2.substr(s2.size() - 4, 4) + "\n";
30489
1/2
✓ Branch 0 taken 12567 times.
✗ Branch 1 not taken.
12567 TraceScriptIDs();
30490
1/2
✓ Branch 0 taken 12567 times.
✗ Branch 1 not taken.
12567 al_trace("%s", s2.c_str());
30491
2/2
✓ Branch 0 taken 2290 times.
✓ Branch 1 taken 10277 times.
12567 if (should_replay_trace)
30492
2/4
✓ Branch 0 taken 2290 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2290 times.
✗ Branch 3 not taken.
2290 replay_step_comment("trace: " + s2);
30493
30494
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12567 times.
12567 if ( console_enabled )
30495 {
30496 zscript_coloured_console.safeprint((CConsoleLoggerEx::COLOR_WHITE |
30497 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK),s2.c_str());
30498 }
30499 12567 }
30500 void FFScript::do_tracel(bool v)
30501 {
30502 int32_t temp = SH::get_arg(sarg1, v);
30503
30504 char tmp[32];
30505 sprintf(tmp, "%d\n", temp);
30506 TraceScriptIDs();
30507 al_trace("%s", tmp);
30508 if (replay_is_active() && replay_get_meta_bool("script_trace"))
30509 replay_step_comment(fmt::format("trace: {}", temp));
30510
30511 if ( console_enabled )
30512 {
30513 zscript_coloured_console.safeprint((CConsoleLoggerEx::COLOR_WHITE |
30514 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK),tmp);
30515 }
30516 }
30517
30518 void FFScript::do_tracebool(const bool v)
30519 {
30520 int32_t temp = SH::get_arg(sarg1, v);
30521 TraceScriptIDs();
30522 char const* str = temp ? "true\n" : "false\n";
30523 al_trace("%s", str);
30524 if (replay_is_active() && replay_get_meta_bool("script_trace"))
30525 replay_step_comment(fmt::format("trace: {}", (bool)temp));
30526
30527 if ( console_enabled )
30528 {
30529 zscript_coloured_console.safeprint((CConsoleLoggerEx::COLOR_WHITE |
30530 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK),str);
30531 }
30532 }
30533
30534 35285 void traceStr(string const& str)
30535 {
30536 35285 FFCore.TraceScriptIDs();
30537 35285 safe_al_trace(str);
30538
7/16
✗ Branch 0 not taken.
✓ Branch 1 taken 35285 times.
✓ Branch 2 taken 35285 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 35285 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 35285 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 35285 times.
✓ Branch 10 taken 1645 times.
✓ Branch 11 taken 33640 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
70570 if (replay_is_active() && replay_get_meta_bool("script_trace"))
30539
1/2
✓ Branch 0 taken 33640 times.
✗ Branch 1 not taken.
33640 replay_step_comment("trace: " + str);
30540
30541
1/2
✓ Branch 0 taken 35285 times.
✗ Branch 1 not taken.
35285 if ( console_enabled )
30542 {
30543 zscript_coloured_console.safeprint((CConsoleLoggerEx::COLOR_WHITE |
30544 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK),str.c_str());
30545 }
30546 35285 }
30547
30548 1389 void FFScript::do_tracestring()
30549 {
30550 1389 int32_t arrayptr = get_register(sarg1);
30551 1389 string str;
30552
1/2
✓ Branch 0 taken 1389 times.
✗ Branch 1 not taken.
1389 ArrayH::getString(arrayptr, str, 512);
30553
1/2
✓ Branch 0 taken 1389 times.
✗ Branch 1 not taken.
1389 str += "\0"; //In the event that the user passed an array w/o NULL, don't crash.
30554
1/2
✓ Branch 0 taken 1389 times.
✗ Branch 1 not taken.
1389 traceStr(str);
30555 1389 }
30556
30557 64358 static int32_t zspr_varg_getter(int32_t,int32_t next_arg)
30558 {
30559 64358 return zs_vargs.at(next_arg);
30560 }
30561 529 static int32_t zspr_stack_getter(int32_t num_args, int32_t next_arg)
30562 {
30563 529 return SH::read_stack(((ri->sp + num_args) - 1) - next_arg);
30564 }
30565
30566 33893 void FFScript::do_printf(const bool v, const bool varg)
30567 {
30568 int32_t num_args, format_arrayptr;
30569
2/2
✓ Branch 0 taken 33606 times.
✓ Branch 1 taken 287 times.
33893 if(varg)
30570 {
30571 33606 num_args = zs_vargs.size();
30572 33606 format_arrayptr = SH::read_stack(ri->sp);
30573 33606 }
30574 else
30575 {
30576 287 num_args = SH::get_arg(sarg1, v) / 10000;
30577 287 format_arrayptr = SH::read_stack(ri->sp + num_args);
30578 }
30579 33893 ArrayManager fmt_am(format_arrayptr);
30580
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33893 times.
33893 if(!fmt_am.invalid())
30581 {
30582 33893 string formatstr;
30583
1/2
✓ Branch 0 taken 33893 times.
✗ Branch 1 not taken.
33893 ArrayH::getString(format_arrayptr, formatstr, MAX_ZC_ARRAY_SIZE);
30584
30585
4/6
✓ Branch 0 taken 33606 times.
✓ Branch 1 taken 287 times.
✓ Branch 2 taken 33893 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 33893 times.
33893 traceStr(zs_sprintf(formatstr.c_str(), num_args, varg ? zspr_varg_getter : zspr_stack_getter));
30586 33893 }
30587
2/2
✓ Branch 0 taken 287 times.
✓ Branch 1 taken 33606 times.
33893 if(varg)
30588 33606 zs_vargs.clear();
30589 33893 }
30590
30591 void FFScript::do_printfarr()
30592 {
30593 int32_t format_arrayptr = SH::read_stack(ri->sp + 1),
30594 args_arrayptr = SH::read_stack(ri->sp + 0);
30595 ArrayManager fmt_am(format_arrayptr);
30596 ArrayManager arg_am(args_arrayptr);
30597 if(!(fmt_am.invalid() || arg_am.invalid()))
30598 {
30599 auto num_args = arg_am.size();
30600 string formatstr;
30601 ArrayH::getString(format_arrayptr, formatstr, MAX_ZC_ARRAY_SIZE);
30602
30603 traceStr(zs_sprintf(formatstr.c_str(), num_args,
30604 [&](int32_t,int32_t next_arg)
30605 {
30606 return arg_am.get(next_arg);
30607 }));
30608 }
30609 }
30610
30611 1570475 void FFScript::do_varg_max()
30612 {
30613 1570475 int32_t num_args = zs_vargs.size();
30614 1570475 int32_t val = std::numeric_limits<int32_t>::min();
30615
1/2
✓ Branch 0 taken 1570475 times.
✗ Branch 1 not taken.
1570475 if (num_args > 0)
30616 1570475 val = zs_vargs.at(0);
30617
2/2
✓ Branch 0 taken 1570475 times.
✓ Branch 1 taken 1570475 times.
3140950 for(auto q = 1; q < num_args; ++q)
30618 {
30619 1570475 int32_t tval = zs_vargs.at(q);
30620
2/2
✓ Branch 0 taken 1245248 times.
✓ Branch 1 taken 325227 times.
1570475 if(tval > val) val = tval;
30621 1570475 }
30622 1570475 zs_vargs.clear();
30623 1570475 SET_D(rEXP1, val);
30624 1570475 }
30625 162607 void FFScript::do_varg_min()
30626 {
30627 162607 int32_t num_args = zs_vargs.size();
30628 162607 int32_t val = std::numeric_limits<int32_t>::max();
30629
1/2
✓ Branch 0 taken 162607 times.
✗ Branch 1 not taken.
162607 if (num_args > 0)
30630 162607 val = zs_vargs.at(0);
30631
2/2
✓ Branch 0 taken 162607 times.
✓ Branch 1 taken 165281 times.
327888 for(auto q = 1; q < num_args; ++q)
30632 {
30633 165281 int32_t tval = zs_vargs.at(q);
30634
2/2
✓ Branch 0 taken 126870 times.
✓ Branch 1 taken 38411 times.
165281 if(tval < val) val = tval;
30635 165281 }
30636 162607 zs_vargs.clear();
30637 162607 SET_D(rEXP1, val);
30638 162607 }
30639 602349 void FFScript::do_varg_choose()
30640 {
30641 602349 int32_t num_args = zs_vargs.size();
30642 602349 int32_t val = 0;
30643
1/2
✓ Branch 0 taken 602349 times.
✗ Branch 1 not taken.
602349 if(num_args > 0)
30644 {
30645 602349 int32_t choice = zc_rand(num_args-1);
30646 602349 val = zs_vargs.at(choice);
30647 602349 }
30648 602349 zs_vargs.clear();
30649 602349 SET_D(rEXP1, val);
30650 602349 }
30651 30 void FFScript::do_varg_makearray(ScriptType type, const uint32_t UID, script_object_type object_type)
30652 {
30653 30 auto vargs = zs_vargs;
30654 30 zs_vargs.clear();
30655
30656 30 size_t size = vargs.size();
30657 30 SET_D(rEXP1, 0);
30658
30659
2/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
30 if (ZScriptVersion::gc_arrays())
30660 {
30661
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 auto* array = script_arrays.create();
30662
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if (!array)
30663 return;
30664
30665 30 ZScriptArray &a = array->arr;
30666
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 a.Resize(size);
30667
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 a.setValid(true);
30668
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 a.setObjectType(object_type);
30669
30670
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 30 times.
76 for(size_t j = 0; j < size; ++j)
30671
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 a[j] = vargs[j]; //initialize array
30672
30673 30 SET_D(rEXP1, array->id);
30674
30675 30 return;
30676 }
30677
30678 dword ptrval;
30679 for(ptrval = 1; localRAM[ptrval].Valid(); ptrval++) ;
30680
30681 if(ptrval >= NUM_ZSCRIPT_ARRAYS)
30682 {
30683 Z_scripterrlog("%d local arrays already in use, no more can be allocated\n", NUM_ZSCRIPT_ARRAYS-1);
30684 ptrval = 0;
30685 }
30686 else
30687 {
30688 ZScriptArray &a = localRAM[ptrval];
30689
30690 a.Resize(size);
30691 a.setValid(true);
30692
30693 for(size_t j = 0; j < size; ++j)
30694 a[j] = vargs[j]; //initialize array
30695
30696 arrayOwner[ptrval].clear();
30697 arrayOwner[ptrval].reown(type, UID);
30698 }
30699
30700 SET_D(rEXP1, ptrval*10000);
30701
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 }
30702
30703 void FFScript::do_breakpoint()
30704 {
30705 // TODO: implement as `debugger;` statement when VS Code extension exists.
30706 }
30707
30708 28 void FFScript::do_tracenl()
30709 {
30710 28 safe_al_trace("\n");
30711
30712
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 if ( console_enabled )
30713 {
30714 zscript_coloured_console.safeprint((CConsoleLoggerEx::COLOR_WHITE |
30715 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK),"\n");
30716 }
30717 28 }
30718
30719
30720 354971 void FFScript::TraceScriptIDs(bool force_show_context)
30721 {
30722 if(DEVTIMESTAMP)
30723 {
30724 CConsoleLoggerEx console = zscript_coloured_console;
30725 bool cond = console_enabled;
30726
30727 char buf[256] = {0};
30728 //Calculate timestamp
30729 struct tm * tm_struct;
30730 time_t sysRTC;
30731 time (&sysRTC);
30732 tm_struct = localtime (&sysRTC);
30733
30734 sprintf(buf, "[%d:%d:%d] ", tm_struct->tm_hour, tm_struct->tm_min, tm_struct->tm_sec);
30735 //
30736
30737 al_trace("%s", buf);
30738 if ( cond ) {console.safeprint((CConsoleLoggerEx::COLOR_GREEN | CConsoleLoggerEx::COLOR_INTENSITY |
30739 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK),buf); }
30740 }
30741
30742
4/4
✓ Branch 0 taken 307119 times.
✓ Branch 1 taken 47852 times.
✓ Branch 2 taken 42669 times.
✓ Branch 3 taken 5183 times.
354971 bool show_context = force_show_context || (get_qr(qr_TRACESCRIPTIDS) || DEVLOGGING);
30743
2/2
✓ Branch 0 taken 5183 times.
✓ Branch 1 taken 349788 times.
354971 if (show_context)
30744 {
30745 349788 CConsoleLoggerEx console = zscript_coloured_console;
30746 349788 bool cond = console_enabled;
30747 349788 char buf[256] = {0};
30748
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 349782 times.
349788 if(script_funcrun)
30749 {
30750
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 sprintf(buf, "Destructor(%d,%s): ", ri->thiskey, destructstr?destructstr->c_str():"UNKNOWN");
30751 6 }
30752
10/18
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 156972 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 30698 times.
✓ Branch 9 taken 53 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 94 times.
✓ Branch 12 taken 3944 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 157960 times.
✗ Branch 17 not taken.
349782 else switch(curScriptType)
30753 {
30754 case ScriptType::Global:
30755 {
30756
2/9
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 157932 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
157960 switch(curScriptNum)
30757 {
30758 case GLOBAL_SCRIPT_INIT:
30759
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 sprintf(buf, "Global Init(%s): ", globalmap[curScriptNum].scriptname.c_str());
30760 28 break;
30761 case GLOBAL_SCRIPT_GAME:
30762
1/2
✓ Branch 0 taken 157932 times.
✗ Branch 1 not taken.
157932 sprintf(buf, "Global Active(%s): ", globalmap[curScriptNum].scriptname.c_str());
30763 157932 break;
30764 case GLOBAL_SCRIPT_END:
30765 sprintf(buf, "Global Exit(%s): ", globalmap[curScriptNum].scriptname.c_str());
30766 break;
30767 case GLOBAL_SCRIPT_ONSAVELOAD:
30768 sprintf(buf, "Global SaveLoad(%s): ", globalmap[curScriptNum].scriptname.c_str());
30769 break;
30770 case GLOBAL_SCRIPT_ONLAUNCH:
30771 sprintf(buf, "Global Launch(%s): ", globalmap[curScriptNum].scriptname.c_str());
30772 break;
30773 case GLOBAL_SCRIPT_ONCONTGAME:
30774 sprintf(buf, "Global ContGame(%s): ", globalmap[curScriptNum].scriptname.c_str());
30775 break;
30776 case GLOBAL_SCRIPT_F6:
30777 sprintf(buf, "Global F6Menu(%s): ", globalmap[curScriptNum].scriptname.c_str());
30778 break;
30779 case GLOBAL_SCRIPT_ONSAVE:
30780 sprintf(buf, "Global Save(%s): ", globalmap[curScriptNum].scriptname.c_str());
30781 break;
30782 }
30783 157960 break;
30784 }
30785
30786 case ScriptType::Hero:
30787 {
30788 switch(curScriptNum)
30789 {
30790 case SCRIPT_HERO_INIT:
30791 sprintf(buf, "Hero Init(%s): ", playermap[curScriptNum-1].scriptname.c_str());
30792 break;
30793 case SCRIPT_HERO_ACTIVE:
30794 sprintf(buf, "Hero Active(%s): ", playermap[curScriptNum-1].scriptname.c_str());
30795 break;
30796 case SCRIPT_HERO_DEATH:
30797 sprintf(buf, "Hero Death(%s): ", playermap[curScriptNum-1].scriptname.c_str());
30798 break;
30799 case SCRIPT_HERO_WIN:
30800 sprintf(buf, "Hero Win(%s): ", playermap[curScriptNum-1].scriptname.c_str());
30801 break;
30802 }
30803 break;
30804 }
30805
30806 case ScriptType::Lwpn:
30807
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 sprintf(buf, "LWeapon(%u, %s): ", curScriptNum,lwpnmap[curScriptNum-1].scriptname.c_str());
30808 48 break;
30809
30810 case ScriptType::Ewpn:
30811
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 sprintf(buf, "EWeapon(%u, %s): ", curScriptNum,ewpnmap[curScriptNum-1].scriptname.c_str());
30812 1 break;
30813
30814 case ScriptType::NPC:
30815 sprintf(buf, "NPC(%u, %s): ", curScriptNum,npcmap[curScriptNum-1].scriptname.c_str());
30816 break;
30817
30818 case ScriptType::FFC:
30819
1/2
✓ Branch 0 taken 156972 times.
✗ Branch 1 not taken.
156972 sprintf(buf, "FFC(%u, %s): ", curScriptNum,ffcmap[curScriptNum-1].scriptname.c_str());
30820 156972 break;
30821
30822 case ScriptType::Item:
30823 sprintf(buf, "Item(%u, %s): ", curScriptNum,itemmap[curScriptNum-1].scriptname.c_str());
30824 break;
30825
30826 case ScriptType::OnMap:
30827 sprintf(buf, "DMapMap(%u, %s): ", curScriptNum,dmapmap[curScriptNum-1].scriptname.c_str());
30828 break;
30829 case ScriptType::ScriptedActiveSubscreen:
30830 sprintf(buf, "DMapASub(%u, %s): ", curScriptNum,dmapmap[curScriptNum-1].scriptname.c_str());
30831 break;
30832 case ScriptType::ScriptedPassiveSubscreen:
30833
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 sprintf(buf, "DMapPSub(%u, %s): ", curScriptNum,dmapmap[curScriptNum-1].scriptname.c_str());
30834 2 break;
30835 case ScriptType::DMap:
30836
1/2
✓ Branch 0 taken 30698 times.
✗ Branch 1 not taken.
30698 sprintf(buf, "DMap(%u, %s): ", curScriptNum,dmapmap[curScriptNum-1].scriptname.c_str());
30837 30698 break;
30838
30839 case ScriptType::ItemSprite:
30840
1/2
✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
53 sprintf(buf, "ItemSprite(%u, %s): ", curScriptNum,itemspritemap[curScriptNum-1].scriptname.c_str());
30841 53 break;
30842
30843 case ScriptType::Screen:
30844
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 sprintf(buf, "Screen(%u, %s): ", curScriptNum,screenmap[curScriptNum-1].scriptname.c_str());
30845 10 break;
30846
30847 case ScriptType::Combo:
30848
1/2
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
94 sprintf(buf, "Combo(%u, %s): ", curScriptNum,comboscriptmap[curScriptNum-1].scriptname.c_str());
30849 94 break;
30850
30851 case ScriptType::Generic:
30852
1/2
✓ Branch 0 taken 3944 times.
✗ Branch 1 not taken.
3944 sprintf(buf, "Generic(%u, %s): ", curScriptNum,genericmap[curScriptNum-1].scriptname.c_str());
30853 3944 break;
30854
30855 case ScriptType::GenericFrozen:
30856 sprintf(buf, "GenericFRZ(%u, %s): ", curScriptNum,genericmap[curScriptNum-1].scriptname.c_str());
30857 break;
30858
30859 case ScriptType::EngineSubscreen:
30860 sprintf(buf, "Subscreen(%u, %s): ", curScriptNum,subscreenmap[curScriptNum-1].scriptname.c_str());
30861 break;
30862 }
30863
30864
1/2
✓ Branch 0 taken 349788 times.
✗ Branch 1 not taken.
349788 al_trace("%s", buf);
30865
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 349788 times.
349788 if ( cond )
30866 console.safeprint((CConsoleLoggerEx::COLOR_GREEN|CConsoleLoggerEx::COLOR_INTENSITY|
30867 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK),buf);
30868 349788 }
30869 354971 }
30870
30871 2 void FFScript::do_cleartrace()
30872 {
30873 2 zc_trace_clear();
30874 2 clearConsole();
30875 2 }
30876
30877 3 string inttobase(word base, int32_t x, word mindigits)
30878 {
30879 static const char coeff[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
30880
30881 3 string s2;
30882
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 word digits = zc_max(mindigits - 1, word(floor(log(double(x)) / log(double(base)))));
30883
30884
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 3 times.
14 for(int32_t i = digits; i >= 0; i--)
30885 {
30886
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
11 s2 += coeff[word(floor(x / pow(double(base), i))) % base];
30887 11 }
30888
30889 3 return s2;
30890
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 }
30891
30892 3 void FFScript::do_tracetobase()
30893 {
30894 3 int32_t x = SH::read_stack(ri->sp + 2) / 10000;
30895 3 uint32_t base = vbound(SH::read_stack(ri->sp + 1) / 10000, 2, 36);
30896
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 uint32_t mindigits = zc_max(1, SH::read_stack(ri->sp) / 10000);
30897
30898
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 string s2 = x < 0 ? "-": "";
30899
30900
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 switch(base)
30901 {
30902 case 8:
30903 s2 += '0';
30904 break;
30905
30906 case 16:
30907 s2 += "0x";
30908 break;
30909 }
30910
30911
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 s2 += inttobase(base, int32_t(fabs(double(x))), mindigits);
30912
30913
2/3
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
3 switch(base)
30914 {
30915 case 8:
30916 case 10:
30917 case 16:
30918 2 break;
30919
30920 case 2:
30921
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 s2 += 'b';
30922 1 break;
30923
30924 default:
30925 std::stringstream ss;
30926 ss << " (Base " << base << ')';
30927 s2 += ss.str();
30928 break;
30929 }
30930
30931
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 s2 += "\n";
30932
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 traceStr(s2);
30933 3 }
30934
30935 int32_t FFScript::getHeroOTile(int32_t index1, int32_t index2)
30936 {
30937 {
30938 herospritetype lst = (herospritetype)index1;
30939 int32_t dir = index2;
30940 int32_t the_ret = 0;
30941 switch(lst)
30942 {
30943 case LSprwalkspr: the_ret = walkspr[dir][0]; break;
30944 case LSprstabspr: the_ret = stabspr[dir][0]; break;
30945 case LSprslashspr: the_ret = slashspr[dir][0]; break;
30946 case LSprrevslashspr: the_ret = revslashspr[dir][0]; break;
30947 case LSprfloatspr: the_ret = floatspr[dir][0]; break;
30948 case LSprswimspr: the_ret = swimspr[dir][0]; break;
30949 case LSprdivespr: the_ret = divespr[dir][0]; break;
30950 case LSprdrownspr: the_ret = drowningspr[dir][0]; break;
30951 case LSprsidedrownspr: the_ret = sidedrowningspr[dir][0]; break;
30952 case LSprlavadrownspr: the_ret = drowning_lavaspr[dir][0]; break;
30953 case LSprsideswimspr: the_ret = sideswimspr[dir][0]; break;
30954 case LSprsideswimslashspr: the_ret = sideswimslashspr[dir][0]; break;
30955 case LSprsideswimstabspr: the_ret = sideswimstabspr[dir][0]; break;
30956 case LSprsideswimpoundspr: the_ret = sideswimpoundspr[dir][0]; break;
30957 case LSprsideswimchargespr: the_ret = sideswimchargespr[dir][0]; break;
30958 case LSprpoundspr: the_ret = poundspr[dir][0]; break;
30959 case LSprjumpspr: the_ret = jumpspr[dir][0]; break;
30960 case LSprchargespr: the_ret = chargespr[dir][0]; break;
30961 case LSprcastingspr: the_ret = castingspr[0]; break;
30962 case LSprsideswimcastingspr: the_ret = sideswimcastingspr[0]; break;
30963 case LSprholdspr1: the_ret = holdspr[0][0][0]; break;
30964 case LSprholdspr2: the_ret = holdspr[0][1][0]; break;
30965 case LSprholdsprw1: the_ret = holdspr[1][0][0]; break;
30966 case LSprholdsprw2: the_ret = holdspr[1][1][0]; break;
30967 case LSprholdsprSw1: the_ret = sideswimholdspr[0][0]; break;
30968 case LSprholdsprSw2: the_ret = sideswimholdspr[1][0]; break;
30969 default: the_ret = 0;
30970 }
30971
30972 return the_ret*10000;
30973 }
30974 }
30975
30976 defWpnSprite FFScript::getDefWeaponSprite(int32_t wpnid)
30977 {
30978 switch(wpnid)
30979 {
30980 case wNone: return ws_0;
30981 case wSword: return ws_0;
30982 case wBeam: return wsBeam;
30983 case wBrang : return wsBrang;
30984 case wBomb: return wsBomb;
30985 case wSBomb: return wsSBomb;
30986 case wLitBomb: return wsBombblast;
30987 case wLitSBomb: return wsBombblast;
30988 case wArrow: return wsArrow;
30989 case wRefArrow: return wsArrow;
30990 case wFire: return wsFire;
30991 case wRefFire: return wsFire;
30992 case wRefFire2: return wsFire;
30993 case wWhistle: return wsUnused45;
30994 case wBait: return wsBait;
30995 case wWand: return wsWandHandle;
30996 case wMagic: return wsMagic;
30997 case wCatching: return wsUnused45;
30998 case wWind: return wsWind;
30999 case wRefMagic: return wsRefMagic;
31000 case wRefFireball: return wsRefFireball;
31001 case wRefRock: return wsRock;
31002 case wHammer: return wsHammer;
31003 case wHookshot: return wsHookshotHead;
31004 case wHSHandle: return wsHookshotHandle;
31005 case wHSChain: return wsHookshotChainH;
31006 case wSSparkle: return wsSilverSparkle;
31007 case wFSparkle: return wsGoldSparkle;
31008 case wSmack: return wsHammerSmack;
31009 case wPhantom: return wsUnused45;
31010 case wCByrna: return wsByrnaCane;
31011 case wRefBeam: return wsRefBeam;
31012 case wStomp: return wsUnused45;
31013 case lwMax: return wsUnused45;
31014 case wScript1:
31015 case wScript2:
31016 case wScript3:
31017 case wScript4:
31018 case wScript5:
31019 case wScript6:
31020 case wScript7:
31021 case wScript8:
31022 case wScript9:
31023 case wScript10: return ws_0;
31024 case wIce: return wsIce; //new
31025 case wFlame: return wsEFire2; //new
31026 //not implemented; t/b/a
31027 case wSound:
31028 case wThrown:
31029 case wPot:
31030 case wLit:
31031 case wBombos:
31032 case wEther:
31033 case wQuake:
31034 case wSword180:
31035 case wSwordLA: return wsUnused45;
31036
31037 case ewFireball: return wsFireball2;
31038 case ewArrow: return wsEArrow;
31039 case ewBrang: return wsBrang;
31040 case ewSword: return wsEBeam;
31041 case ewRock: return wsRock;
31042 case ewMagic: return wsEMagic;
31043 case ewBomb: return wsEBomb;
31044 case ewSBomb: return wsESbomb;
31045 case ewLitBomb: return wsEBombblast;
31046 case ewLitSBomb: return wsESbombblast;
31047 case ewFireTrail: return wsEFiretrail;
31048 case ewFlame: return wsEFire;
31049 case ewWind: return wsEWind;
31050 case ewFlame2: return wsEFire2;
31051 case ewFlame2Trail: return wsEFiretrail2;
31052 case ewIce: return wsIce;
31053 case ewFireball2: return wsFireball2;
31054 default: return wsUnused45;
31055 }
31056 };
31057
31058 598 void FFScript::do_loadlweapon_by_script_uid(const bool v)
31059 {
31060 598 int32_t uid = SH::get_arg(sarg1, v);
31061
1/2
✓ Branch 0 taken 598 times.
✗ Branch 1 not taken.
598 if (ResolveLWeapon_checkSpriteList(uid))
31062 598 ri->lwpnref = uid;
31063 else
31064 {
31065 ri->lwpnref = 0;
31066 }
31067 598 }
31068
31069 void FFScript::do_loadeweapon_by_script_uid(const bool v)
31070 {
31071 int32_t uid = SH::get_arg(sarg1, v);
31072 if (ResolveEWeapon_checkSpriteList(uid))
31073 ri->ewpnref = uid;
31074 else
31075 {
31076 ri->ewpnref = 0;
31077 }
31078 }
31079
31080
31081 12 void FFScript::do_loadnpc_by_script_uid(const bool v)
31082 {
31083 12 int32_t uid = SH::get_arg(sarg1, v);
31084
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (ResolveSprite<enemy>(uid, "enemy"))
31085 12 ri->npcref = uid;
31086 else
31087 {
31088 ri->npcref = 0;
31089 }
31090 12 }
31091
31092 //Combo Scripts
31093
31094 104700 void FFScript::clear_combo_scripts()
31095 {
31096 104700 combo_id_cache.clear();
31097 104700 combo_id_cache.resize(region_num_rpos * 7);
31098 104700 std::fill(combo_id_cache.begin(), combo_id_cache.end(), -1);
31099 104700 FFCore.deallocateAllScriptOwnedOfType(ScriptType::Combo);
31100 104700 FFCore.clear_script_engine_data_of_type(ScriptType::Combo);
31101 104700 }
31102
31103 8607 void FFScript::clear_combo_script(const rpos_handle_t& rpos_handle)
31104 {
31105 8607 int32_t index = get_combopos_ref(rpos_handle);
31106 8607 combo_id_cache[index] = -1;
31107 8607 combopos_modified = index;
31108 8607 clear_script_engine_data(ScriptType::Combo, index);
31109 8607 }
31110
31111 4842804 int32_t FFScript::combo_script_engine(const bool preload, const bool waitdraw)
31112 {
31113 bool enabled[7];
31114
2/2
✓ Branch 0 taken 33899628 times.
✓ Branch 1 taken 4842804 times.
38742432 for (int32_t q = 0; q < 7; ++q)
31115 {
31116 33899628 enabled[q] = get_qr(qr_COMBOSCRIPTS_LAYER_0 + q);
31117 33899628 }
31118
31119 4842804 auto& combo_cache = combo_caches::script;
31120
31121 ///non-scripted effects
31122 3620415028 for_every_rpos([&](const rpos_handle_t& rpos_handle) {
31123
2/2
✓ Branch 0 taken 1448614464 times.
✓ Branch 1 taken 2166957760 times.
3615572224 if (!enabled[rpos_handle.layer])
31124 2166957760 return;
31125
31126 1448614464 int32_t combopos_ref = get_combopos_ref(rpos_handle);
31127 1448614464 word cid = rpos_handle.data();
31128
2/2
✓ Branch 0 taken 1446590604 times.
✓ Branch 1 taken 2023860 times.
1448614464 if(combo_id_cache[combopos_ref] != cid)
31129 {
31130 2023860 combopos_modified = combopos_ref;
31131 2023860 combo_id_cache[combopos_ref] = cid;
31132 2023860 clear_script_engine_data(ScriptType::Combo, combopos_ref);
31133 2023860 }
31134
31135 1448614464 auto script = combo_cache.minis[cid].script;
31136
2/2
✓ Branch 0 taken 1435564508 times.
✓ Branch 1 taken 13049956 times.
1448614464 if (script)
31137 {
31138 13049956 auto& data = get_script_engine_data(ScriptType::Combo, combopos_ref);
31139
2/2
✓ Branch 0 taken 12194395 times.
✓ Branch 1 taken 855561 times.
13049956 if (data.doscript)
31140 {
31141
4/4
✓ Branch 0 taken 423943 times.
✓ Branch 1 taken 431618 times.
✓ Branch 2 taken 419660 times.
✓ Branch 3 taken 4283 times.
855561 if (waitdraw && !data.waitdraw) return; //waitdraw not set
31142
31143 435901 ZScriptVersion::RunScript(ScriptType::Combo, script, combopos_ref);
31144
2/2
✓ Branch 0 taken 431618 times.
✓ Branch 1 taken 4283 times.
435901 if (waitdraw) data.waitdraw = true;
31145 435901 }
31146 12630296 }
31147 3615572224 });
31148
31149 4842804 return 1;
31150 }
31151
31152 823245 int32_t FFScript::Distance(double x1, double y1, double x2, double y2)
31153 {
31154 823245 double x = (x1-x2);
31155 823245 double y = (y1-y2);
31156 823245 double sum = (x*x)+(y*y);
31157 //if(((int32_t)sum) < 0)
31158 //{
31159 // Z_scripterrlog("Distance() attempted to calculate square root of %ld!\n", ((int32_t)sum));
31160 // return -10000;;
31161 //}
31162 823245 sum *= 1000000.0;
31163 823245 double total = sqrt(sum)*10;
31164 823245 return int32_t(total);
31165 }
31166
31167 int32_t FFScript::Distance(double x1, double y1, double x2, double y2, int32_t scale)
31168 {
31169 double x3 = x1+(x2-x1)/scale;
31170 double y3 = y1+(y2-y1)/scale;
31171 //double sum = (x*x)+(y*y);
31172 //if(((int32_t)sum) < 0)
31173 //{
31174 // Z_scripterrlog("Distance() attempted to calculate square root of %ld!\n", ((int32_t)sum));
31175 // return -10000;
31176 //}
31177 //sum *= 1000000.0;
31178 //double total = sqrt(sum)*10;
31179 //return int32_t(total*scale);
31180 return (FFCore.Distance(x1, y1, x3, y3)*scale);
31181 }
31182
31183 int32_t FFScript::LongDistance(double x1, double y1, double x2, double y2)
31184 {
31185 double x = (x1-x2);
31186 double y = (y1-y2);
31187 double sum = (x*x)+(y*y);
31188 //if(((int32_t)sum) < 0)
31189 //{
31190 // Z_scripterrlog("Distance() attempted to calculate square root of %ld!\n", ((int32_t)sum));
31191 // return -10000;;
31192 //}
31193 double total = sqrt(sum);
31194 return int32_t(total);
31195 }
31196
31197 int32_t FFScript::LongDistance(double x1, double y1, double x2, double y2, int32_t scale)
31198 {
31199 double x3 = x1+(x2-x1)/scale;
31200 double y3 = y1+(y2-y1)/scale;
31201 //double sum = (x*x)+(y*y);
31202 //if(((int32_t)sum) < 0)
31203 //{
31204 // Z_scripterrlog("Distance() attempted to calculate square root of %ld!\n", ((int32_t)sum));
31205 // return -10000;
31206 //}
31207 //sum *= 1000000.0;
31208 //double total = sqrt(sum)*10;
31209 //return int32_t(total*scale);
31210 return (FFCore.LongDistance(x1, y1, x3, y3)*scale);
31211 }
31212
31213 420699029 bool command_is_wait(int command)
31214 {
31215
2/2
✓ Branch 0 taken 420509288 times.
✓ Branch 1 taken 189741 times.
420699029 switch (command)
31216 {
31217 case WAITFRAME:
31218 case WAITDRAW:
31219 case WAITTO:
31220 case WAITEVENT:
31221 case WAITFRAMESR:
31222 189741 return true;
31223 }
31224 420509288 return false;
31225 420699029 }
31226
31227 298861055 bool command_is_goto(int command)
31228 {
31229 // GOTOR/return ops left out on purpose.
31230
2/2
✓ Branch 0 taken 277551167 times.
✓ Branch 1 taken 21309888 times.
298861055 switch (command)
31231 {
31232 case GOTO:
31233 case GOTOCMP:
31234 case GOTOLESS:
31235 case GOTOMORE:
31236 case GOTOTRUE:
31237 case GOTOFALSE:
31238 21309888 return true;
31239 }
31240 277551167 return false;
31241 298861055 }
31242
31243 100453802 bool command_uses_comparison_result(int command)
31244 {
31245
2/2
✓ Branch 0 taken 96037861 times.
✓ Branch 1 taken 4415941 times.
100453802 switch (command)
31246 {
31247 case GOTOTRUE:
31248 case GOTOFALSE:
31249 case GOTOMORE:
31250 case GOTOLESS:
31251 case GOTOCMP:
31252 case SETCMP:
31253 case SETTRUE:
31254 case SETTRUEI:
31255 case SETFALSE:
31256 case SETFALSEI:
31257 case SETMOREI:
31258 case SETLESSI:
31259 case SETMORE:
31260 case SETLESS:
31261 case STACKWRITEATVV_IF:
31262 4415941 return true;
31263 }
31264 96037861 return false;
31265 100453802 }
31266
31267 200862630 bool command_writes_comparison_result(int command)
31268 {
31269
2/2
✓ Branch 0 taken 192666932 times.
✓ Branch 1 taken 8195698 times.
200862630 switch (command)
31270 {
31271 case SETCMP:
31272 case SETTRUE:
31273 case SETTRUEI:
31274 case SETFALSE:
31275 case SETFALSEI:
31276 case SETMOREI:
31277 case SETLESSI:
31278 case SETMORE:
31279 case SETLESS:
31280 8195698 return true;
31281 }
31282 192666932 return false;
31283 200862630 }
31284
31285 13443386 int command_to_cmp(int command, int arg)
31286 {
31287
12/14
✓ Branch 0 taken 2319825 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3238616 times.
✓ Branch 3 taken 5658 times.
✓ Branch 4 taken 81778 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3086359 times.
✓ Branch 7 taken 1407483 times.
✓ Branch 8 taken 1824589 times.
✓ Branch 9 taken 766449 times.
✓ Branch 10 taken 431380 times.
✓ Branch 11 taken 52696 times.
✓ Branch 12 taken 191023 times.
✓ Branch 13 taken 37530 times.
13443386 switch (command)
31288 {
31289 case SETCMP:
31290 case GOTOCMP:
31291 2319825 return arg;
31292
31293 case GOTOTRUE:
31294 3238616 return CMP_EQ;
31295 case GOTOFALSE:
31296 5658 return CMP_NE;
31297 case GOTOMORE:
31298 81778 return CMP_GE;
31299 case GOTOLESS:
31300 return get_qr(qr_GOTOLESSNOTEQUAL) ? CMP_LE : CMP_LT;
31301
31302 case SETTRUE:
31303 3086359 return CMP_EQ;
31304 case SETFALSE:
31305 1407483 return CMP_NE;
31306 case SETMORE:
31307 1824589 return CMP_GE;
31308 case SETLESS:
31309 766449 return CMP_LE;
31310
31311 case SETTRUEI:
31312 431380 return CMP_SETI|CMP_EQ;
31313 case SETFALSEI:
31314 52696 return CMP_SETI|CMP_NE;
31315 case SETMOREI:
31316 191023 return CMP_SETI|CMP_GE;
31317 case SETLESSI:
31318 37530 return CMP_SETI|CMP_LE;
31319 }
31320
31321 ASSERT(false);
31322 return 0;
31323 13443386 }
31324
31325 1450992 bool command_could_return_not_ok(int command)
31326 {
31327
2/2
✓ Branch 0 taken 1448082 times.
✓ Branch 1 taken 2910 times.
1450992 switch (command)
31328 {
31329 case 0xFFFF:
31330 case EWPNDEL:
31331 case GAMECONTINUE:
31332 case GAMEEND:
31333 case GAMEEXIT:
31334 case GAMERELOAD:
31335 case GAMESAVECONTINUE:
31336 case GAMESAVEQUIT:
31337 case ITEMDEL:
31338 case LWPNDEL:
31339 case NPCKICKBUCKET:
31340 2910 return true;
31341 }
31342 1448082 return false;
31343 1450992 }
31344
31345 172524288 bool command_is_pure(int command)
31346 {
31347
2/2
✓ Branch 0 taken 118497921 times.
✓ Branch 1 taken 54026367 times.
172524288 switch (command)
31348 {
31349 case ABS:
31350 case ADDR:
31351 case ADDV:
31352 case ANDR:
31353 case ANDR32:
31354 case ANDV:
31355 case ANDV32:
31356 case ARCCOSR:
31357 case ARCSINR:
31358 case BITNOT:
31359 case BITNOT32:
31360 case CASTBOOLF:
31361 case CEILING:
31362 case COMPAREV2:
31363 case COSR:
31364 case COSV:
31365 case DIVR:
31366 case DIVV:
31367 case DIVV2:
31368 case FACTORIAL:
31369 case FLOOR:
31370 case IPOWERR:
31371 case IPOWERV:
31372 case ISALLOCATEDBITMAP:
31373 case LOAD:
31374 case LOADD:
31375 case LOADI:
31376 case LOG10:
31377 case LOGE:
31378 case LPOWERR:
31379 case LPOWERV:
31380 case LPOWERV2:
31381 case LSHIFTR:
31382 case LSHIFTR32:
31383 case LSHIFTV:
31384 case LSHIFTV32:
31385 case MAXR:
31386 case MAXV:
31387 case MINR:
31388 case MINV:
31389 case MODR:
31390 case MODV:
31391 case MODV2:
31392 case MULTR:
31393 case MULTV:
31394 case NANDR:
31395 case NANDV:
31396 case NORR:
31397 case NORV:
31398 case NOT:
31399 case ORR:
31400 case ORR32:
31401 case ORV:
31402 case ORV32:
31403 case PEEK:
31404 case PEEKATV:
31405 case POWERR:
31406 case POWERV:
31407 case POWERV2:
31408 case ROUND:
31409 case ROUNDAWAY:
31410 case RSHIFTR:
31411 case RSHIFTR32:
31412 case RSHIFTV:
31413 case RSHIFTV32:
31414 case SETCMP:
31415 case SETFALSE:
31416 case SETFALSEI:
31417 case SETLESS:
31418 case SETLESSI:
31419 case SETMORE:
31420 case SETMOREI:
31421 case SETR:
31422 case SETTRUE:
31423 case SETTRUEI:
31424 case SETV:
31425 case SINR:
31426 case SINV:
31427 case SQROOTR:
31428 case SQROOTV:
31429 case SUBR:
31430 case SUBV:
31431 case SUBV2:
31432 case TANR:
31433 case TANV:
31434 case TOBYTE:
31435 case TOINTEGER:
31436 case TOSHORT:
31437 case TOSIGNEDBYTE:
31438 case TOWORD:
31439 case TRUNCATE:
31440 case XNORR:
31441 case XNORV:
31442 case XORR:
31443 case XORR32:
31444 case XORV:
31445 case XORV32:
31446 54026367 return true;
31447 }
31448
31449 118497921 return false;
31450 172524288 }
31451
31452 1448635425 int32_t get_combopos_ref(const rpos_handle_t& rpos_handle)
31453 {
31454 1448635425 return rpos_handle.layer * region_num_rpos + (int)rpos_handle.rpos;
31455 }
31456
31457 int32_t get_combopos_ref(rpos_t rpos, int32_t layer)
31458 {
31459 return layer * region_num_rpos + (int)rpos;
31460 }
31461
31462 1381722 rpos_t combopos_ref_to_rpos(int32_t combopos_ref)
31463 {
31464 1381722 return (rpos_t)(combopos_ref % region_num_rpos);
31465 }
31466
31467 455086 int32_t combopos_ref_to_layer(int32_t combopos_ref)
31468 {
31469 455086 return combopos_ref / region_num_rpos;
31470 }
31471
31472 ScriptEngineData& get_ffc_script_engine_data(int index)
31473 {
31474 return get_script_engine_data(ScriptType::FFC, index);
31475 }
31476
31477 1648949 ScriptEngineData& get_item_script_engine_data(int index)
31478 {
31479 1648949 return get_script_engine_data(ScriptType::Item, index);
31480 }
31481
31482 #ifdef DEBUG_REGISTER_DEPS
31483
31484 static std::array<int, 8> debug_deps_cur_regs;
31485 static int debug_ref;
31486
31487 #define REG_R ((int)ARGTY::READ_REG)
31488 #define REG_W ((int)ARGTY::WRITE_REG)
31489
31490 int debug_get_d(int r)
31491 {
31492 CHECK(!(debug_deps_cur_regs[r] & REG_W));
31493 debug_deps_cur_regs[r] |= REG_R;
31494 return ri->d[r];
31495 }
31496
31497 int debug_set_d(int r, int v)
31498 {
31499 debug_deps_cur_regs[r] |= REG_W;
31500 return ri->d[r];
31501 }
31502
31503 int debug_get_ref(std::string reg_name)
31504 {
31505 util::upperstr(reg_name);
31506 util::replstr(reg_name, "REF", "");
31507 reg_name = "REF" + reg_name;
31508 int r = get_script_variable(reg_name).value();
31509 return debug_get_ref(r);
31510 }
31511
31512 int debug_get_ref(int r)
31513 {
31514 if (r == debug_ref) return get_ref(r);
31515
31516 CHECK(!debug_ref);
31517 debug_ref = r;
31518 return get_ref(r);
31519 }
31520
31521 static const char* get_d_reg_name(int r)
31522 {
31523 if (r == 0) return "rINDEX";
31524 if (r == 1) return "rINDEX2";
31525 if (r == 2) return "rEXP1";
31526 if (r == 3) return "rEXP2";
31527 if (r == 4) return "rSFRAME";
31528 if (r == 5) return "rNUL";
31529 if (r == 6) return "rSFTEMP";
31530 if (r == 7) return "rWHAT_NO_7";
31531 NOTREACHED();
31532 }
31533
31534 static void reset_test_ri(refInfo* ri)
31535 {
31536 *ri = {};
31537 ri->sp = MAX_STACK_SIZE - 100;
31538 ri->screenref = cur_screen;
31539 ri->msgdataref = -1;
31540 }
31541
31542 void print_d_register_deps()
31543 {
31544 refInfo testRi;
31545 ri = &testRi;
31546 std::array<int32_t, MAX_STACK_SIZE> testStack{};
31547 testStack.fill(10000);
31548 stack = (int32_t (*)[MAX_STACK_SIZE])testStack.data();
31549
31550 // value -> case labels
31551 std::map<std::string, std::vector<std::string>> value_to_labels;
31552 std::map<std::string, std::vector<std::string>> value_to_labels2;
31553
31554 for (int i = 0; i < NUMVARIABLES; i++)
31555 {
31556 auto [sv, _] = get_script_variable(i);
31557 if (!sv) continue;
31558
31559 reset_test_ri(&testRi);
31560 for (int j = 0; j < 8; j++) ri->d[j] = i == 4891 ? 10000 : 0;
31561
31562 debug_deps_cur_regs = {};
31563 debug_ref = 0;
31564 get_register(i);
31565
31566 bool any = false;
31567 for (int j = 0; j < 8; j++)
31568 {
31569 if (debug_deps_cur_regs[j])
31570 any = true;
31571 }
31572
31573 if (any)
31574 {
31575 std::vector<std::string> reg_names;
31576 for (int j = 0; j < 8; j++)
31577 {
31578 CHECK(!(debug_deps_cur_regs[j] & REG_W));
31579 if (!debug_deps_cur_regs[j])
31580 continue;
31581
31582 reg_names.push_back(get_d_reg_name(j));
31583 }
31584
31585 std::string value = fmt::format("{{{}}}", fmt::join(reg_names, ", "));
31586 if (auto* labels = util::find(value_to_labels, value))
31587 labels->push_back(sv->name);
31588 else
31589 value_to_labels[value] = {sv->name};
31590 }
31591
31592 if (debug_ref)
31593 {
31594 std::string value = get_script_variable(debug_ref).first->name;
31595 if (auto* labels = util::find(value_to_labels2, value))
31596 labels->push_back(sv->name);
31597 else
31598 value_to_labels2[value] = {sv->name};
31599 }
31600 }
31601
31602 fmt::println("static std::vector<int> _get_register_dependencies(int reg)");
31603 fmt::println("{{");
31604 fmt::println("\tswitch (reg)");
31605 fmt::println("\t{{");
31606
31607 for (auto& [value, labels] : value_to_labels | std::views::reverse)
31608 {
31609 std::sort(labels.begin(), labels.end());
31610 for (auto& label : labels)
31611 fmt::println("\t\tcase {}:", label);
31612 fmt::println("\t\t{{");
31613 fmt::println("\t\t\treturn {};", value);
31614 fmt::println("\t\t}}");
31615 fmt::println("");
31616 }
31617 value_to_labels.clear();
31618
31619 fmt::println("\t}}");
31620 fmt::println("");
31621 fmt::println("\treturn {{}};");
31622 fmt::println("}}");
31623
31624 fmt::println("std::optional<int> get_register_ref_dependency(int reg)");
31625 fmt::println("{{");
31626 fmt::println("\tswitch (reg)");
31627 fmt::println("\t{{");
31628
31629 for (auto& [value, labels] : value_to_labels2)
31630 {
31631 std::sort(labels.begin(), labels.end());
31632 for (auto& label : labels)
31633 fmt::println("\t\tcase {}:", label);
31634 fmt::println("\t\t\treturn {};", value);
31635 fmt::println("");
31636 }
31637
31638 fmt::println("\t}}");
31639 fmt::println("");
31640 fmt::println("\treturn {{}};");
31641 fmt::println("}}");
31642
31643 curscript = new script_data(ScriptType::None, 0);
31644 curscript->zasm_script = std::make_shared<zasm_script>();
31645
31646 JittedScriptInstance j_instance{};
31647 j_instance.script = curscript;
31648
31649 for (int i = 0; i < NUMCOMMANDS; i++)
31650 {
31651 if (command_is_goto(i) || command_is_wait(i) || command_uses_comparison_result(i) || command_writes_comparison_result(i))
31652 continue;
31653
31654 switch (i)
31655 {
31656 case CALLFUNC:
31657 case CLOSEWIPE:
31658 case CLOSEWIPESHAPE:
31659 case DEALLOCATEMEMR:
31660 case FXWAVYR:
31661 case FXWAVYV:
31662 case FXZAPR:
31663 case FXZAPV:
31664 case GAMECONTINUE:
31665 case GAMEEND:
31666 case GAMEEXIT:
31667 case GAMERELOAD:
31668 case GAMESAVECONTINUE:
31669 case GAMESAVEQUIT:
31670 case GOTOR:
31671 case LOAD_INTERNAL_ARRAY_REF:
31672 case LOAD_INTERNAL_ARRAY:
31673 case MARK_TYPE_REG:
31674 case OBJ_OWN_ARRAY:
31675 case OBJ_OWN_BITMAP:
31676 case OBJ_OWN_DIR:
31677 case OBJ_OWN_FILE:
31678 case OBJ_OWN_PALDATA:
31679 case OBJ_OWN_RNG:
31680 case OBJ_OWN_STACK:
31681 case OPENWIPE:
31682 case OPENWIPESHAPE:
31683 case POP:
31684 case POPARGS:
31685 case PUSHARGSR:
31686 case PUSHARGSV:
31687 case PUSHR:
31688 case PUSHV:
31689 case QUIT:
31690 case RETURN:
31691 case RETURNFUNC:
31692 case SAVE:
31693 case SAVEQUITSCREEN:
31694 case SAVESCREEN:
31695 case SET_OBJECT:
31696 case SHOWF6SCREEN:
31697 case STARTDESTRUCTOR:
31698 case WAVYIN:
31699 case WAVYOUT:
31700 case ZAPIN:
31701 case ZAPOUT:
31702 case ZCLASS_CONSTRUCT:
31703 case ZCLASS_MARK_TYPE:
31704 continue;
31705 }
31706
31707 if (!get_script_command(i))
31708 continue;
31709
31710 curscript->zasm_script->zasm.push_back({(word)i});
31711 }
31712
31713 curscript->zasm_script->zasm.push_back({NOP});
31714 curscript->zasm_script->size = curscript->end_pc = curscript->zasm_script->zasm.size();
31715
31716 for (int i = 0; i < curscript->zasm_script->size; i++)
31717 {
31718 reset_test_ri(&testRi);
31719
31720 debug_deps_cur_regs = {};
31721 debug_ref = 0;
31722
31723 int command = curscript->zasm_script->zasm[i].command;
31724 auto sc = get_script_command(command);
31725
31726 switch (command)
31727 {
31728 case REF_DEC:
31729 case REF_INC:
31730 {
31731 debug_deps_cur_regs[rSFRAME] = REG_R;
31732 break;
31733 }
31734
31735 default:
31736 {
31737 run_script_jit_one(&j_instance, i, MAX_STACK_SIZE - 100);
31738 }
31739 }
31740
31741 bool any = false;
31742 for (int j = 0; j < 8; j++)
31743 {
31744 if (debug_deps_cur_regs[j])
31745 any = true;
31746 if (debug_deps_cur_regs[j] & REG_W)
31747 CHECK(!command_is_pure(command));
31748 }
31749 if (!any)
31750 continue;
31751
31752 std::vector<std::string> parts;
31753 for (int j = 0; j < 8; j++)
31754 {
31755 if (!debug_deps_cur_regs[j])
31756 continue;
31757
31758 bool r = debug_deps_cur_regs[j] & REG_R;
31759 bool w = debug_deps_cur_regs[j] & REG_W;
31760 std::string value;
31761 if (r && w) value = "REG_RW";
31762 else if (r) value = "REG_R";
31763 else if (w) value = "REG_W";
31764
31765 parts.push_back(fmt::format("{{{}, {}}}", get_d_reg_name(j), value));
31766 }
31767
31768 std::string value = fmt::format("{{{}}}", fmt::join(parts, ", "));
31769 if (auto* labels = util::find(value_to_labels, value))
31770 labels->push_back(sc->name);
31771 else
31772 value_to_labels[value] = {sc->name};
31773 }
31774
31775 value_to_labels["{{CLASS_THISKEY, REG_W}}"] = {"ZCLASS_MARK_TYPE"};
31776 value_to_labels["{{rEXP1, REG_R}, {CLASS_THISKEY, REG_W}}"] = {"ZCLASS_CONSTRUCT"};
31777 value_to_labels["{{SP, REG_RW}, {SP2, REG_RW}}"] = {"POP", "POPARGS", "PUSHARGSR", "PUSHARGSV", "PUSHR", "PUSHV"};
31778
31779 fmt::println("std::initializer_list<CommandDependency> get_command_implicit_dependencies(int command)");
31780 fmt::println("{{");
31781 fmt::println("\ttypedef std::initializer_list<CommandDependency> T;");
31782 fmt::println("");
31783 fmt::println("\tswitch (command)");
31784 fmt::println("\t{{");
31785
31786 for (auto& [value, labels] : value_to_labels | std::views::reverse)
31787 {
31788 std::sort(labels.begin(), labels.end());
31789 for (auto& label : labels)
31790 fmt::println("\t\tcase {}:", label);
31791 fmt::println("\t\t{{");
31792 fmt::println("\t\t\tstatic T r = {};", value);
31793 fmt::println("\t\t\treturn r;");
31794 fmt::println("\t\t}}");
31795 fmt::println("");
31796 }
31797 value_to_labels.clear();
31798
31799 fmt::println("\t}}");
31800 fmt::println("");
31801 fmt::println("\treturn {{}};");
31802 fmt::println("}}");
31803
31804 exit(0);
31805 }
31806
31807 #endif
31808